Skip to content

Strange keyof behavior with combination of Partial and Record. #28839

Closed
@fenying

Description

@fenying

TypeScript Version: 3.2.1

Search Terms:
keyof, Record, Partial, ...

But actually, I don't know how to exactly express this problem in the search box...

Code

// A *self-contained* demonstration of the problem follows...
// Test this by running `tsc` on the command-line, rather than through another build tool such as Gulp, Webpack, etc.

interface ITest {

    a: string;
}

type PartialRecord<K extends keyof any, T> = {

    [k in K]?: T;
};

class SlotTest<ES> {

    private _slots1: Partial<Record<keyof ES, ITest>> = {};

    private _slots2: Record<keyof ES, ITest> = {} as any;

    private _slots3: PartialRecord<keyof ES, ITest> = {};

    public doTest1<K extends keyof ES>(name: K): void {

        /**
         * It works well in v2.9.x, but fails in v3.2.1.
         * [ts] Type '{ a: string; }' is not assignable to type 'Record<keyof ES, ITest>[K]'. [2322]
         */
        this._slots1[name] = {"a": "ggg"};
    }

    public doTest2<K extends keyof ES>(name: K): void {

        /**
         * This works fine.
         */
        this._slots2[name] = {"a": "ggg"};
    }

    public doTest3<K extends keyof ES>(name: K): void {

        /**
         * This works fine.
         */
        this._slots3[name] = {"a": "ggg"};
    }
}

Expected behavior:

When I used v2.9.2, the code works well.

Actual behavior:

But, when I upgrade to v3.2.1, it fails with compilation error message like this:

Type '{ "a": string; }' is not assignable to type 'Record<keyof ES, ITest>[K]'.

Playground Link:

Related Issues:

#18538 maybe

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptDomain: Indexed Access TypesThe issue relates to accessing subtypes via index accessDomain: Mapped TypesThe issue relates to mapped typesFixedA PR has been merged for this issue

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions