Skip to content

String Indexer Assignable to Generic Mapped Type #28798

Description

TypeScript Version: Version 3.3.0-dev

Search Terms: string indexer generic mapped type assignable

Code
This seems like a regression (if it is a bug). I get the expected behaviour on the playground 3.1.

functiontester<Kextends'a'>(x: Record<K,number>,y: {[x: string]: number}){x=y;// no error: not expectedy=x;// no error: expected}functiontester2(x: Record<'a',number>,y: {[x: string]: number}){x=y;// error: expectedy=x;// no error: expected}

Expected behavior:

A string indexer should not be assignable to a mapped type with a generic constraint.

Actual behavior:

String indexer appears to be assignable to generic record type.

Playground Link:playground with expected behaviour

Update. I think this was introduced by #28218.

// A source type T is related to a target type { [P in Q]: X } if Q is related to keyof T and T[Q] is related to X.if(!isGenericMappedType(source)&&isRelatedTo(getConstraintTypeFromMappedType(target),getIndexType(source))){constindexedAccessType=getIndexedAccessType(source,getTypeParameterFromMappedType(target));consttemplateType=getTemplateTypeFromMappedType(target);if(result=isRelatedTo(indexedAccessType,templateType,reportErrors)){returnresult;}}

In this instance we have 'a' is related string, but a type with a key set of type string is not guaranteed to have the key a. When relating keys I think string and number should really be bottom types, so a possible fix is to filter them from the source index type:

filterType(getIndexType(source),t=>!(t.flags&(TypeFlags.String|TypeFlags.Number)// and symbol??

Metadata

Metadata

Labels

BugA bug in TypeScript

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions