Skip to content

Redefine Object.keys to use keyof #20503

@fathyb

Description

@fathyb

TypeScript Version: 2.6.2

Code

interface MyIFace {
    key1: string
    key2: number
}
const MyObject: {[K in keyof MyIFace]: string} = {
    key1: 'foo',
    key2: 'bar'
}

declare function someFunction(key: keyof MyIFace): void

// error: Argument of type 'string' is not assignable to parameter of type '"key1" | "key2"'
Object.keys(MyObject).forEach(key => someFunction(key))

// error: Type 'string' is not assignable to type '"key1" | "key2"'
Object.keys(MyObject).forEach((key: keyof MyIFace) => someFunction(key))
Object.keys(MyObject).forEach((key: keyof typeof MyObject) => someFunction(key))

Expected behavior:

Object.keys(MyObject) should type it's return as (keyof typeof MyObject)[].

Actual behavior:

Object.keys(MyObject) types it's return as string[].

This can be easily fixed by defining Object.keys as follow :

declare const BetterObject: {
    keys<T extends {}>(object: T): (keyof T)[]
}

// OR

declare const BetterObject: {
    keys(object: {}): (keyof typeof object)[]
}

// everything works and key is infered as "key1" | "key2"
BetterObject.keys(MyObject).forEach(key => someFunction(key))
BetterObject.keys(MyObject).forEach((key: keyof MyIFace) => someFunction(key))
BetterObject.keys(MyObject).forEach((key: keyof typeof MyObject) => someFunction(key))

Metadata

Metadata

Assignees

No one assigned

    Labels

    DuplicateAn existing issue was already created

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions