Skip to content

Object.keys fails on generic types #40089

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

Closed
wants to merge 1 commit into from
Closed

Object.keys fails on generic types #40089

wants to merge 1 commit into from

Conversation

millsp
Copy link
Contributor

@millsp millsp commented Aug 17, 2020

const clone = <B extends A>(b: B): B => {
    // @ts-ignore
    const clone = (new b.constructor) as B

    for (const key of Object.keys(b)) {
        b[key] // should not error
    }

    return clone
}

The error comes from the fact that .keys() returned string[]. When working with generic types, TypeScript is unsure that a string key will exist within the generic type B (not known). TypeScript can only agree if key is of type keyof B, that explains the change.

```ts
const clone = <B extends A>(b: B): B => {
    // @ts-ignore
    const clone = (new b.constructor) as B

    for (const key of Object.keys(b)) {
        b[key] // should not error
    }

    return clone
}
```

The error comes from the fact that `.keys()` returned `string[]`. When working with generic types, TypeScript is unsure that a `string` key will exist within the generic type `B` (not known). TypeScript can only agree if `key` is of type `keyof B`, that explains the change.
@typescript-bot typescript-bot added the For Uncommitted Bug PR for untriaged, rejected, closed or missing bug label Aug 17, 2020
@j-oliveras
Copy link
Contributor

j-oliveras commented Aug 17, 2020

This was rejected multiple times: #38328, #34639, #34500, #30314 and others (search Object.keys in closed issues and closed PR)

See: https://stackoverflow.com/questions/55012174/why-doesnt-object-keys-return-a-keyof-type-in-typescript

Simple example that is a bad idea:

const a = {
        c: 1,
        d: 2,
};

const b: { c: number } = a;

Object.keys(b); // With your types that will be ("c")[], but is ("c" | "d")[]

@millsp
Copy link
Contributor Author

millsp commented Aug 17, 2020

Thanks @j-oliveras

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
For Uncommitted Bug PR for untriaged, rejected, closed or missing bug
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants