Skip to content

Mapped generic types lose index signature #23080

Description

@tyrielv

TypeScript Version: 2.9.0-dev.20180402

Search Terms: partial mapped types index signature enum

Code

enum Fruits {
    Mango = 0,
    Banana = 1
}

interface IFruitMetadata<T> {
    [Fruits.Mango]: T;
    [Fruits.Banana]: T;
}

const onSale1: IFruitMetadata<boolean> = {
    [Fruits.Mango]: true,
    [Fruits.Banana]: false
};

const onSale2: Partial<IFruitMetadata<boolean>> = {
    [Fruits.Banana]: true,
};

const onSale3: Pick<IFruitMetadata<boolean>, Fruits.Banana> = {
    [Fruits.Banana]: true,
};

onSale1[Fruits.Banana] = true;
onSale2[Fruits.Mango] = true;
onSale3[Fruits.Banana] = true;

Expected behavior:
No compile errors. This was the behavior in 2.7.2.
Actual behavior:
With noImplicitAny=true, the Partial and Pick versions of the type triggers error TS7017: Element implicitly has an 'any' type because type 'Partial<IFruitMetadata>' has no index signature.
Playground Link

#22892 looks like it might be related.

Activity

  1. changed the title [-]Mapped types lose index signature[/-] [+]Mapped generic types lose index signature[/+] on Apr 2, 2018
  2. mhegazy commented on Apr 3, 2018

    @mhegazy
    Contributor

    Wesley Wigham (@weswigham) this should be fixed by #23090, correct?

  3. weswigham commented on Apr 3, 2018

    @weswigham
    Member

    I think so? But Anders Hejlsberg (@ahejlsberg) was unenthused with that fix and was looking for a more holistic approach to the problems and inconsistencies we have in the keyof area in general. (Though I may have a revision that's a little closer to acceptable)

  4. mhegazy commented on Apr 3, 2018

    @mhegazy
    Contributor

    Spoke to Anders Hejlsberg (@ahejlsberg), he has a different proposal for adding a new indexof operator. should address both issues.

  5. dardino commented on Apr 23, 2018

    @dardino

    Another example:

    enum MyEnum {
        ValA = 0,
        ValB = 1,
    }
    
    type IEnumTpProp<R> = {[key in keyof typeof MyEnum]: R };
    
    var X: IEnumTpProp<string> = {
        ValA: "text1",
        ValB: "text2",
        0: "error" // expected: error;  current: error; //OK
    };
    
    X[MyEnum[MyEnum.ValA]] = "no error"; // current: no error; expected: no error // **OK**
    X[MyEnum.ValA] = "no error??"; // current: no error; expected: error // **KO**
  6. mhegazy commented on Apr 26, 2018

    @mhegazy
    Contributor

    Sample described in OP should be fixed by #23592.

    Gabriele (@dardino) the behavior in your example is expected, since enums have a numeric index signature.
    with #23592 you can write something like:

    enum MyEnum {
        ValA = 0,
        ValB = 1,
    }
    
    type IEnumTpProp<R> = { [key in MyEnum]: R };
    
    var X: IEnumTpProp<string> = {
        [MyEnum.ValA]: "text1",
        [MyEnum.ValB]: "text2",
        0 :""  //Error, duplicate entry
    };
  7. locked and limited conversation to collaborators on Jul 31, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

BugA bug in TypeScriptFixedA PR has been merged for this issue

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions