Skip to content

keyof has different literal type behavior when used in function signature #20602

Closed
@asmundg

Description

@asmundg

Apologies in advance for any imprecise use of terminology. Hopefully, the example code demonstrates what I'm trying to say. :)

TypeScript Version: 2.7.0-dev.20171209

Code

interface Foo {
    a: number
    b: number
}

// No error
const k: keyof Foo = "a"
const u: { a: number } | { b: number } = { [k]: 1 }

function foo(k2: keyof Foo): void {
    /**
     * error TS2322: Type '{ [x: string]: number; }' is not assignable to type '{ a: number; } | { b: number; }'.
     *   Type '{ [x: string]: number; }' is not assignable to type '{ b: number; }'.
     *     Property 'b' is missing in type '{ [x: string]: number; }'.
     */
    const u: { a: number } | { b: number } = { [k2]: 1 }
}

Expected behavior:

It seems like keyof should produce the same literal type in both cases and never widen the type when used as the key in an object literal.

Actual behavior:

In practice, keyof produces the expected literal type when used in a const declaration, but produces a type that widens to string when used in a function signature.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Working as IntendedThe behavior described is the intended behavior; this is not a bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions