diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 0f2b62bf4937c..474f062c9da6e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -17034,7 +17034,7 @@ namespace ts { function instantiateMappedTupleType(tupleType: TupleTypeReference, mappedType: MappedType, mapper: TypeMapper) { const elementFlags = tupleType.target.elementFlags; const elementTypes = map(getTypeArguments(tupleType), (_, i) => - instantiateMappedTypeTemplate(mappedType, getStringLiteralType("" + i), !!(elementFlags[i] & ElementFlags.Optional), mapper)); + instantiateMappedTypeTemplate(mappedType, getNumberLiteralType(i), !!(elementFlags[i] & ElementFlags.Optional), mapper)); const modifiers = getMappedTypeModifiers(mappedType); const newTupleModifiers = modifiers & MappedTypeModifiers.IncludeOptional ? map(elementFlags, f => f & ElementFlags.Required ? ElementFlags.Optional : f) : modifiers & MappedTypeModifiers.ExcludeOptional ? map(elementFlags, f => f & ElementFlags.Optional ? ElementFlags.Required : f) : diff --git a/tests/baselines/reference/mappedTypeTupleTypePropType.js b/tests/baselines/reference/mappedTypeTupleTypePropType.js new file mode 100644 index 0000000000000..d0cb6685c84c8 --- /dev/null +++ b/tests/baselines/reference/mappedTypeTupleTypePropType.js @@ -0,0 +1,40 @@ +//// [mappedTypeTupleTypePropType.ts] +type Indices> = { + [K in keyof T]: K +}; + +// should contain numbers +type MyIndices = Indices<[string, number]>; +// union of indices should be preserved +type StillMyIndices = MyIndices[number] & number + +// simplified repro from https://twitter.com/oleg008/status/1508422774401949704 + +type Container = { + value: V; +}; + +type UnwrapContainers[]> = { + [K in keyof T]: T[K & number]["value"]; +}; + +declare function combine[]>( + containers: [...T], + callback: (...values: UnwrapContainers) => void +): void; + +declare const container1: Container; +declare const container2: Container; + +combine([container1, container2], (value1, value2) => { + const val1: string = value1; + const val2: number = value2; +}); + + + +//// [mappedTypeTupleTypePropType.js] +combine([container1, container2], function (value1, value2) { + var val1 = value1; + var val2 = value2; +}); diff --git a/tests/baselines/reference/mappedTypeTupleTypePropType.symbols b/tests/baselines/reference/mappedTypeTupleTypePropType.symbols new file mode 100644 index 0000000000000..3971a27f71450 --- /dev/null +++ b/tests/baselines/reference/mappedTypeTupleTypePropType.symbols @@ -0,0 +1,91 @@ +=== tests/cases/compiler/mappedTypeTupleTypePropType.ts === +type Indices> = { +>Indices : Symbol(Indices, Decl(mappedTypeTupleTypePropType.ts, 0, 0)) +>T : Symbol(T, Decl(mappedTypeTupleTypePropType.ts, 0, 13)) +>Array : Symbol(Array, Decl(lib.es5.d.ts, --, --), Decl(lib.es5.d.ts, --, --)) + + [K in keyof T]: K +>K : Symbol(K, Decl(mappedTypeTupleTypePropType.ts, 1, 3)) +>T : Symbol(T, Decl(mappedTypeTupleTypePropType.ts, 0, 13)) +>K : Symbol(K, Decl(mappedTypeTupleTypePropType.ts, 1, 3)) + +}; + +// should contain numbers +type MyIndices = Indices<[string, number]>; +>MyIndices : Symbol(MyIndices, Decl(mappedTypeTupleTypePropType.ts, 2, 2)) +>Indices : Symbol(Indices, Decl(mappedTypeTupleTypePropType.ts, 0, 0)) + +// union of indices should be preserved +type StillMyIndices = MyIndices[number] & number +>StillMyIndices : Symbol(StillMyIndices, Decl(mappedTypeTupleTypePropType.ts, 5, 43)) +>MyIndices : Symbol(MyIndices, Decl(mappedTypeTupleTypePropType.ts, 2, 2)) + +// simplified repro from https://twitter.com/oleg008/status/1508422774401949704 + +type Container = { +>Container : Symbol(Container, Decl(mappedTypeTupleTypePropType.ts, 7, 48)) +>V : Symbol(V, Decl(mappedTypeTupleTypePropType.ts, 11, 15)) + + value: V; +>value : Symbol(value, Decl(mappedTypeTupleTypePropType.ts, 11, 21)) +>V : Symbol(V, Decl(mappedTypeTupleTypePropType.ts, 11, 15)) + +}; + +type UnwrapContainers[]> = { +>UnwrapContainers : Symbol(UnwrapContainers, Decl(mappedTypeTupleTypePropType.ts, 13, 2)) +>T : Symbol(T, Decl(mappedTypeTupleTypePropType.ts, 15, 22)) +>Container : Symbol(Container, Decl(mappedTypeTupleTypePropType.ts, 7, 48)) + + [K in keyof T]: T[K & number]["value"]; +>K : Symbol(K, Decl(mappedTypeTupleTypePropType.ts, 16, 3)) +>T : Symbol(T, Decl(mappedTypeTupleTypePropType.ts, 15, 22)) +>T : Symbol(T, Decl(mappedTypeTupleTypePropType.ts, 15, 22)) +>K : Symbol(K, Decl(mappedTypeTupleTypePropType.ts, 16, 3)) + +}; + +declare function combine[]>( +>combine : Symbol(combine, Decl(mappedTypeTupleTypePropType.ts, 17, 2)) +>T : Symbol(T, Decl(mappedTypeTupleTypePropType.ts, 19, 25)) +>Container : Symbol(Container, Decl(mappedTypeTupleTypePropType.ts, 7, 48)) + + containers: [...T], +>containers : Symbol(containers, Decl(mappedTypeTupleTypePropType.ts, 19, 57)) +>T : Symbol(T, Decl(mappedTypeTupleTypePropType.ts, 19, 25)) + + callback: (...values: UnwrapContainers) => void +>callback : Symbol(callback, Decl(mappedTypeTupleTypePropType.ts, 20, 21)) +>values : Symbol(values, Decl(mappedTypeTupleTypePropType.ts, 21, 13)) +>UnwrapContainers : Symbol(UnwrapContainers, Decl(mappedTypeTupleTypePropType.ts, 13, 2)) +>T : Symbol(T, Decl(mappedTypeTupleTypePropType.ts, 19, 25)) + +): void; + +declare const container1: Container; +>container1 : Symbol(container1, Decl(mappedTypeTupleTypePropType.ts, 24, 13)) +>Container : Symbol(Container, Decl(mappedTypeTupleTypePropType.ts, 7, 48)) + +declare const container2: Container; +>container2 : Symbol(container2, Decl(mappedTypeTupleTypePropType.ts, 25, 13)) +>Container : Symbol(Container, Decl(mappedTypeTupleTypePropType.ts, 7, 48)) + +combine([container1, container2], (value1, value2) => { +>combine : Symbol(combine, Decl(mappedTypeTupleTypePropType.ts, 17, 2)) +>container1 : Symbol(container1, Decl(mappedTypeTupleTypePropType.ts, 24, 13)) +>container2 : Symbol(container2, Decl(mappedTypeTupleTypePropType.ts, 25, 13)) +>value1 : Symbol(value1, Decl(mappedTypeTupleTypePropType.ts, 27, 35)) +>value2 : Symbol(value2, Decl(mappedTypeTupleTypePropType.ts, 27, 42)) + + const val1: string = value1; +>val1 : Symbol(val1, Decl(mappedTypeTupleTypePropType.ts, 28, 7)) +>value1 : Symbol(value1, Decl(mappedTypeTupleTypePropType.ts, 27, 35)) + + const val2: number = value2; +>val2 : Symbol(val2, Decl(mappedTypeTupleTypePropType.ts, 29, 7)) +>value2 : Symbol(value2, Decl(mappedTypeTupleTypePropType.ts, 27, 42)) + +}); + + diff --git a/tests/baselines/reference/mappedTypeTupleTypePropType.types b/tests/baselines/reference/mappedTypeTupleTypePropType.types new file mode 100644 index 0000000000000..ebd0a26a6833b --- /dev/null +++ b/tests/baselines/reference/mappedTypeTupleTypePropType.types @@ -0,0 +1,70 @@ +=== tests/cases/compiler/mappedTypeTupleTypePropType.ts === +type Indices> = { +>Indices : Indices + + [K in keyof T]: K +}; + +// should contain numbers +type MyIndices = Indices<[string, number]>; +>MyIndices : [0, 1] + +// union of indices should be preserved +type StillMyIndices = MyIndices[number] & number +>StillMyIndices : StillMyIndices + +// simplified repro from https://twitter.com/oleg008/status/1508422774401949704 + +type Container = { +>Container : Container + + value: V; +>value : V + +}; + +type UnwrapContainers[]> = { +>UnwrapContainers : UnwrapContainers + + [K in keyof T]: T[K & number]["value"]; +}; + +declare function combine[]>( +>combine : []>(containers: [...T], callback: (...values: UnwrapContainers) => void) => void + + containers: [...T], +>containers : [...T] + + callback: (...values: UnwrapContainers) => void +>callback : (...values: UnwrapContainers) => void +>values : UnwrapContainers + +): void; + +declare const container1: Container; +>container1 : Container + +declare const container2: Container; +>container2 : Container + +combine([container1, container2], (value1, value2) => { +>combine([container1, container2], (value1, value2) => { const val1: string = value1; const val2: number = value2;}) : void +>combine : []>(containers: [...T], callback: (...values: UnwrapContainers) => void) => void +>[container1, container2] : [Container, Container] +>container1 : Container +>container2 : Container +>(value1, value2) => { const val1: string = value1; const val2: number = value2;} : (value1: string, value2: number) => void +>value1 : string +>value2 : number + + const val1: string = value1; +>val1 : string +>value1 : string + + const val2: number = value2; +>val2 : number +>value2 : number + +}); + + diff --git a/tests/cases/compiler/mappedTypeTupleTypePropType.ts b/tests/cases/compiler/mappedTypeTupleTypePropType.ts new file mode 100644 index 0000000000000..9dea1d773fcba --- /dev/null +++ b/tests/cases/compiler/mappedTypeTupleTypePropType.ts @@ -0,0 +1,32 @@ +type Indices> = { + [K in keyof T]: K +}; + +// should contain numbers +type MyIndices = Indices<[string, number]>; +// union of indices should be preserved +type StillMyIndices = MyIndices[number] & number + +// simplified repro from https://twitter.com/oleg008/status/1508422774401949704 + +type Container = { + value: V; +}; + +type UnwrapContainers[]> = { + [K in keyof T]: T[K & number]["value"]; +}; + +declare function combine[]>( + containers: [...T], + callback: (...values: UnwrapContainers) => void +): void; + +declare const container1: Container; +declare const container2: Container; + +combine([container1, container2], (value1, value2) => { + const val1: string = value1; + const val2: number = value2; +}); +