Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mapped types over keyof T should be subtypes of types with string index signatures #14548

Closed
cwmacdon opened this issue Mar 8, 2017 · 6 comments · Fixed by #17633
Closed
Assignees
Labels
Committed The team has roadmapped this issue Fixed A PR has been merged for this issue Suggestion An idea for TypeScript

Comments

@cwmacdon
Copy link

cwmacdon commented Mar 8, 2017

TypeScript Version: 2.2.1

Code

// helpers to map types
type Dictionary = {
    [key: string]: string;
};

interface IBaseEntity {
    name: string;
    properties: Dictionary;
}
interface IEntity<t> extends IBaseEntity {
    properties: Record<t, string>;
}

Expected behaviour:
No Compile error.

Actual behaviour:
Compile error:

Interface 'IEntity<t>' incorrectly extends interface 'IBaseEntity'.
  Types of property 'properties' are incompatible.
    Type 'Record<t, string>' is not assignable to type 'Dictionary'.

Edit: Replace StrictDictionary with Record<t, string>. Show full compile error.

@mhegazy
Copy link
Contributor

mhegazy commented Mar 9, 2017

I suppose if the source is a generic mapped type, and the target only has string indexer, then the two types are relatable iff the template type of the source is relatable to the type of the index signature of the target.

@mhegazy mhegazy added Suggestion An idea for TypeScript In Discussion Not yet reached consensus labels Mar 9, 2017
@cwmacdon
Copy link
Author

cwmacdon commented Mar 9, 2017

So you're saying if we constrain the generic type in StrictDictionary<t> then theoretically it would be reasonable for this to work?

@mhegazy
Copy link
Contributor

mhegazy commented Mar 9, 2017

I am saying this is a new type compatibility rule we need to encode in the compiler.

@cwmacdon
Copy link
Author

cwmacdon commented Mar 9, 2017

It would also be nice if the return type of Object.keys() on a StrictDictionary<t, u> was keyof t.

@krryan
Copy link

krryan commented Mar 9, 2017

The problem with that idea, @cwmacdon is that our "StrictDictionary" might actually be something that extends StrictDictionary<t> and so Object.keys() would return strings that are not keyof t. Yet another use-case for nominal typing...

@DanielRosenwasser DanielRosenwasser changed the title keyof t should be a subtype of string Mapped types over keyof T should be subtypes of types with string index signatures Mar 13, 2017
@RyanCavanaugh RyanCavanaugh added Committed The team has roadmapped this issue and removed In Discussion Not yet reached consensus labels Mar 14, 2017
@RyanCavanaugh RyanCavanaugh added this to the TypeScript 2.3 milestone Mar 14, 2017
@wclr
Copy link

wclr commented Mar 19, 2017

Is it in the nightly build yet?

@ahejlsberg ahejlsberg added the Fixed A PR has been merged for this issue label Aug 5, 2017
@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Committed The team has roadmapped this issue Fixed A PR has been merged for this issue Suggestion An idea for TypeScript
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants