tsafe
tsafe copied to clipboard
Enable to typesafely compose Object.fromEntries and Object.entries
It would be really powerful to be able to apply transformation to an object using the well-known pattern:
const transformedObject= Object.fromEntries(
Object.entries(originalObject)
.map(([key, value])=> [key, f(value)]
);
And have TypeScript infers the type of transformedObject
based on the transformation applied to the values f(value)
.
We are half way there already with the utilities:
But the typing of fromEntires()
would have to be improved a bit so that the following example would pass:
import { Reflect }Â from "tsafe/Reflect";
import { assert } from "tsafe/assert";
import type { Equals } from "tsafe";
import { objectEntries } from "tsafe/objectEntries";
import { fromEntires } from "tsafe/objectFromEntries";
const originalObject = Reflect<{
a: string;
b: string;
}>();
const modifiedObject = objectFromEntries(
objectEntries(originalObject)
.map(([key, value]) => [key, value.length] as const)
);
type ExpectedTypeOfModifiedObject = {
a: number;
b: number;
};
assert<Equals<typeof modifiedObject, ExpectedTypeOfModifiedObject>>();
In the current version of tsafe we're getting this:
The test that would have to pass in src/test/objectFromEntires.types.ts
:
{
const originalObject = Reflect<Record<"a" | "b",string>>();
const entries = objectEntries(originalObject);
assert<Equals<typeof entries, (["a", string] | ["b", string])[]>>();
const transformedEntries = entries.map(([key, value]) => [key, value.length] as const);
assert<Equals<typeof transformedEntries, (readonly ["a" | "b", number])[]>>();
const modifiedObject = objectFromEntries(transformedEntries);
assert<Equals<typeof modifiedObject, Record<"a" | "b", number>>>();
}
That looks nice and it should be perfectly possible! I am currently working on an internal project that does something related. I will keep you updated!