Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable to typesafely compose Object.fromEntries and Object.entries #18

Open
garronej opened this issue Oct 9, 2022 · 2 comments
Open

Comments

@garronej
Copy link
Owner

garronej commented Oct 9, 2022

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:
image

@garronej
Copy link
Owner Author

garronej commented Oct 9, 2022

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>>>();

}

@garronej garronej mentioned this issue Oct 11, 2022
@danieldietrich
Copy link
Contributor

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!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants