Skip to content

No-op mapped type not assignable; but original type is assignable #38235

@AnyhowStep

Description

@AnyhowStep

TypeScript Version: 3.8.3

Search Terms:

no-op mapped type, assignable

Code

type Foo<IdentifierT extends Record<PropertyKey, PropertyKey>> =
    IdentifierT
;

type Bar<IdentifierT extends Record<PropertyKey, PropertyKey>, T> =
    {
        [k in keyof T] : Foo<IdentifierT & { k : k }>
    }
;

type Merge2<T> = { [k in keyof T] : T[k] }
type Bar2<IdentifierT extends Record<PropertyKey, PropertyKey>, T> =
    {
        [k in keyof T]: Foo<Merge2<IdentifierT & { k: k }>>
        //                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        //                  Works in 3.5.1
        //                  Works in 3.6.3
        //                  Works in 3.7.5
        //                  Fails in 3.8.3
    }
;

type Identity<T> = T;
type Merge3<T> = Identity<{ [k in keyof T] : T[k] }>
type Bar3<IdentifierT extends Record<PropertyKey, PropertyKey>, T> =
    {
        [k in keyof T]: Foo<Merge3<IdentifierT & { k: k }>>
        //                  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        //                  Works in 3.5.1
        //                  Works in 3.6.3
        //                  Works in 3.7.5
        //                  Fails in 3.8.3
    }
;

Expected behavior:

Passes type checking

Actual behavior:

Fails in TS 3.8.3

Playground Link:

Playground

Related Issues:

Not that I could find


Well, it isn't exactly a "no-op" mapped type.

It will strip call and constructor signatures, but "no-op mapped type" was the best name I had for it.

Metadata

Metadata

Assignees

Labels

BugA bug in TypeScriptFix AvailableA PR has been opened for this issue

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions