Skip to content

Commit 061338e

Browse files
authored
Don't inferFromIndexTypes() twice (#34501)
* Don't inferFromIndexTypes() twice * Add tests
1 parent 5c8def9 commit 061338e

10 files changed

+145
-36
lines changed

src/compiler/checker.ts

+26-26
Original file line numberDiff line numberDiff line change
@@ -18537,6 +18537,32 @@ namespace ts {
1853718537
}
1853818538
// Infer from the members of source and target only if the two types are possibly related
1853918539
if (!typesDefinitelyUnrelated(source, target)) {
18540+
if (isArrayType(source) || isTupleType(source)) {
18541+
if (isTupleType(target)) {
18542+
const sourceLength = isTupleType(source) ? getLengthOfTupleType(source) : 0;
18543+
const targetLength = getLengthOfTupleType(target);
18544+
const sourceRestType = isTupleType(source) ? getRestTypeOfTupleType(source) : getElementTypeOfArrayType(source);
18545+
const targetRestType = getRestTypeOfTupleType(target);
18546+
const fixedLength = targetLength < sourceLength || sourceRestType ? targetLength : sourceLength;
18547+
for (let i = 0; i < fixedLength; i++) {
18548+
inferFromTypes(i < sourceLength ? getTypeArguments(<TypeReference>source)[i] : sourceRestType!, getTypeArguments(target)[i]);
18549+
}
18550+
if (targetRestType) {
18551+
const types = fixedLength < sourceLength ? getTypeArguments(<TypeReference>source).slice(fixedLength, sourceLength) : [];
18552+
if (sourceRestType) {
18553+
types.push(sourceRestType);
18554+
}
18555+
if (types.length) {
18556+
inferFromTypes(getUnionType(types), targetRestType);
18557+
}
18558+
}
18559+
return;
18560+
}
18561+
if (isArrayType(target)) {
18562+
inferFromIndexTypes(source, target);
18563+
return;
18564+
}
18565+
}
1854018566
inferFromProperties(source, target);
1854118567
inferFromSignatures(source, target, SignatureKind.Call);
1854218568
inferFromSignatures(source, target, SignatureKind.Construct);
@@ -18545,32 +18571,6 @@ namespace ts {
1854518571
}
1854618572

1854718573
function inferFromProperties(source: Type, target: Type) {
18548-
if (isArrayType(source) || isTupleType(source)) {
18549-
if (isTupleType(target)) {
18550-
const sourceLength = isTupleType(source) ? getLengthOfTupleType(source) : 0;
18551-
const targetLength = getLengthOfTupleType(target);
18552-
const sourceRestType = isTupleType(source) ? getRestTypeOfTupleType(source) : getElementTypeOfArrayType(source);
18553-
const targetRestType = getRestTypeOfTupleType(target);
18554-
const fixedLength = targetLength < sourceLength || sourceRestType ? targetLength : sourceLength;
18555-
for (let i = 0; i < fixedLength; i++) {
18556-
inferFromTypes(i < sourceLength ? getTypeArguments(<TypeReference>source)[i] : sourceRestType!, getTypeArguments(target)[i]);
18557-
}
18558-
if (targetRestType) {
18559-
const types = fixedLength < sourceLength ? getTypeArguments(<TypeReference>source).slice(fixedLength, sourceLength) : [];
18560-
if (sourceRestType) {
18561-
types.push(sourceRestType);
18562-
}
18563-
if (types.length) {
18564-
inferFromTypes(getUnionType(types), targetRestType);
18565-
}
18566-
}
18567-
return;
18568-
}
18569-
if (isArrayType(target)) {
18570-
inferFromIndexTypes(source, target);
18571-
return;
18572-
}
18573-
}
1857418574
const properties = getPropertiesOfObjectType(target);
1857518575
for (const targetProp of properties) {
1857618576
const sourceProp = getPropertyOfType(source, targetProp.escapedName);

tests/baselines/reference/correctOrderOfPromiseMethod.js

+7-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ async function countEverything(): Promise<number> {
1515
const [resultA, resultB] = await Promise.all([
1616
providerA(),
1717
providerB(),
18-
] as const);
18+
]);
1919

2020
const dataA: A[] = resultA;
2121
const dataB: B[] = resultB;
@@ -24,6 +24,10 @@ async function countEverything(): Promise<number> {
2424
}
2525
return 0;
2626
}
27+
28+
// #31179
29+
30+
const expected: Promise<["a", "b", "c"]> = Promise.all(undefined as readonly ["a", "b", "c"]);
2731

2832

2933
//// [correctOrderOfPromiseMethod.js]
@@ -92,3 +96,5 @@ function countEverything() {
9296
});
9397
});
9498
}
99+
// #31179
100+
var expected = Promise.all(undefined);

tests/baselines/reference/correctOrderOfPromiseMethod.symbols

+11-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ async function countEverything(): Promise<number> {
4343
providerB(),
4444
>providerB : Symbol(providerB, Decl(correctOrderOfPromiseMethod.ts, 11, 9))
4545

46-
] as const);
46+
]);
4747

4848
const dataA: A[] = resultA;
4949
>dataA : Symbol(dataA, Decl(correctOrderOfPromiseMethod.ts, 18, 9))
@@ -70,3 +70,13 @@ async function countEverything(): Promise<number> {
7070
return 0;
7171
}
7272

73+
// #31179
74+
75+
const expected: Promise<["a", "b", "c"]> = Promise.all(undefined as readonly ["a", "b", "c"]);
76+
>expected : Symbol(expected, Decl(correctOrderOfPromiseMethod.ts, 28, 5))
77+
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
78+
>Promise.all : Symbol(PromiseConstructor.all, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --) ... and 6 more)
79+
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
80+
>all : Symbol(PromiseConstructor.all, Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --) ... and 6 more)
81+
>undefined : Symbol(undefined)
82+

tests/baselines/reference/correctOrderOfPromiseMethod.types

+15-5
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,12 @@ async function countEverything(): Promise<number> {
2828
const [resultA, resultB] = await Promise.all([
2929
>resultA : A[]
3030
>resultB : B[]
31-
>await Promise.all([ providerA(), providerB(), ] as const) : [A[], B[]]
32-
>Promise.all([ providerA(), providerB(), ] as const) : Promise<[A[], B[]]>
31+
>await Promise.all([ providerA(), providerB(), ]) : [A[], B[]]
32+
>Promise.all([ providerA(), providerB(), ]) : Promise<[A[], B[]]>
3333
>Promise.all : { <TAll>(values: Iterable<TAll | PromiseLike<TAll>>): Promise<TAll[]>; <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>, T9 | PromiseLike<T9>, T10 | PromiseLike<T10>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; <T1, T2, T3, T4, T5, T6, T7, T8, T9>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>, T9 | PromiseLike<T9>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; <T1, T2, T3, T4, T5, T6, T7, T8>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>; <T1, T2, T3, T4, T5, T6, T7>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>]): Promise<[T1, T2, T3, T4, T5, T6, T7]>; <T1, T2, T3, T4, T5, T6>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>]): Promise<[T1, T2, T3, T4, T5, T6]>; <T1, T2, T3, T4, T5>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>]): Promise<[T1, T2, T3, T4, T5]>; <T1, T2, T3, T4>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>]): Promise<[T1, T2, T3, T4]>; <T1, T2, T3>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>]): Promise<[T1, T2, T3]>; <T1, T2>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>]): Promise<[T1, T2]>; <T>(values: readonly (T | PromiseLike<T>)[]): Promise<T[]>; }
3434
>Promise : PromiseConstructor
3535
>all : { <TAll>(values: Iterable<TAll | PromiseLike<TAll>>): Promise<TAll[]>; <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>, T9 | PromiseLike<T9>, T10 | PromiseLike<T10>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; <T1, T2, T3, T4, T5, T6, T7, T8, T9>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>, T9 | PromiseLike<T9>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; <T1, T2, T3, T4, T5, T6, T7, T8>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>; <T1, T2, T3, T4, T5, T6, T7>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>]): Promise<[T1, T2, T3, T4, T5, T6, T7]>; <T1, T2, T3, T4, T5, T6>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>]): Promise<[T1, T2, T3, T4, T5, T6]>; <T1, T2, T3, T4, T5>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>]): Promise<[T1, T2, T3, T4, T5]>; <T1, T2, T3, T4>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>]): Promise<[T1, T2, T3, T4]>; <T1, T2, T3>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>]): Promise<[T1, T2, T3]>; <T1, T2>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>]): Promise<[T1, T2]>; <T>(values: readonly (T | PromiseLike<T>)[]): Promise<T[]>; }
36-
>[ providerA(), providerB(), ] as const : readonly [Promise<A[]>, Promise<B[]>]
37-
>[ providerA(), providerB(), ] : readonly [Promise<A[]>, Promise<B[]>]
36+
>[ providerA(), providerB(), ] : [Promise<A[]>, Promise<B[]>]
3837

3938
providerA(),
4039
>providerA() : Promise<A[]>
@@ -44,7 +43,7 @@ async function countEverything(): Promise<number> {
4443
>providerB() : Promise<B[]>
4544
>providerB : () => Promise<B[]>
4645

47-
] as const);
46+
]);
4847

4948
const dataA: A[] = resultA;
5049
>dataA : A[]
@@ -72,3 +71,14 @@ async function countEverything(): Promise<number> {
7271
>0 : 0
7372
}
7473

74+
// #31179
75+
76+
const expected: Promise<["a", "b", "c"]> = Promise.all(undefined as readonly ["a", "b", "c"]);
77+
>expected : Promise<["a", "b", "c"]>
78+
>Promise.all(undefined as readonly ["a", "b", "c"]) : Promise<["a", "b", "c"]>
79+
>Promise.all : { <TAll>(values: Iterable<TAll | PromiseLike<TAll>>): Promise<TAll[]>; <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>, T9 | PromiseLike<T9>, T10 | PromiseLike<T10>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; <T1, T2, T3, T4, T5, T6, T7, T8, T9>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>, T9 | PromiseLike<T9>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; <T1, T2, T3, T4, T5, T6, T7, T8>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>; <T1, T2, T3, T4, T5, T6, T7>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>]): Promise<[T1, T2, T3, T4, T5, T6, T7]>; <T1, T2, T3, T4, T5, T6>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>]): Promise<[T1, T2, T3, T4, T5, T6]>; <T1, T2, T3, T4, T5>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>]): Promise<[T1, T2, T3, T4, T5]>; <T1, T2, T3, T4>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>]): Promise<[T1, T2, T3, T4]>; <T1, T2, T3>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>]): Promise<[T1, T2, T3]>; <T1, T2>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>]): Promise<[T1, T2]>; <T>(values: readonly (T | PromiseLike<T>)[]): Promise<T[]>; }
80+
>Promise : PromiseConstructor
81+
>all : { <TAll>(values: Iterable<TAll | PromiseLike<TAll>>): Promise<TAll[]>; <T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>, T9 | PromiseLike<T9>, T10 | PromiseLike<T10>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]>; <T1, T2, T3, T4, T5, T6, T7, T8, T9>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>, T9 | PromiseLike<T9>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8, T9]>; <T1, T2, T3, T4, T5, T6, T7, T8>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>, T8 | PromiseLike<T8>]): Promise<[T1, T2, T3, T4, T5, T6, T7, T8]>; <T1, T2, T3, T4, T5, T6, T7>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>, T7 | PromiseLike<T7>]): Promise<[T1, T2, T3, T4, T5, T6, T7]>; <T1, T2, T3, T4, T5, T6>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>, T6 | PromiseLike<T6>]): Promise<[T1, T2, T3, T4, T5, T6]>; <T1, T2, T3, T4, T5>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>, T5 | PromiseLike<T5>]): Promise<[T1, T2, T3, T4, T5]>; <T1, T2, T3, T4>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>, T4 | PromiseLike<T4>]): Promise<[T1, T2, T3, T4]>; <T1, T2, T3>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>, T3 | PromiseLike<T3>]): Promise<[T1, T2, T3]>; <T1, T2>(values: readonly [T1 | PromiseLike<T1>, T2 | PromiseLike<T2>]): Promise<[T1, T2]>; <T>(values: readonly (T | PromiseLike<T>)[]): Promise<T[]>; }
82+
>undefined as readonly ["a", "b", "c"] : readonly ["a", "b", "c"]
83+
>undefined : undefined
84+

tests/baselines/reference/restTupleElements1.types

+1-1
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ f0([]); // Error
173173
>[] : []
174174

175175
f0([1]);
176-
>f0([1]) : [number, number]
176+
>f0([1]) : [number, unknown]
177177
>f0 : <T, U>(x: [T, ...U[]]) => [T, U]
178178
>[1] : [number]
179179
>1 : 1

tests/baselines/reference/typeInferenceWithTupleType.js

+11
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ var zipResult = zip(["foo", "bar"], [5, 6]);
2323
var zipResultEle = zipResult[0]; // [string, number]
2424
var zipResultEleEle = zipResult[0][0]; // string
2525

26+
// #33559 and #33752
27+
28+
declare function f1<T1, T2>(values: [T1[], T2[]]): T1;
29+
declare function f2<T1, T2>(values: readonly [T1[], T2[]]): T1;
30+
31+
let expected: "a";
32+
expected = f1(undefined as ["a"[], "b"[]]);
33+
expected = f2(undefined as ["a"[], "b"[]]);
2634

2735

2836
//// [typeInferenceWithTupleType.js]
@@ -46,3 +54,6 @@ function zip(array1, array2) {
4654
var zipResult = zip(["foo", "bar"], [5, 6]);
4755
var zipResultEle = zipResult[0]; // [string, number]
4856
var zipResultEleEle = zipResult[0][0]; // string
57+
var expected;
58+
expected = f1(undefined);
59+
expected = f2(undefined);

tests/baselines/reference/typeInferenceWithTupleType.symbols

+32
Original file line numberDiff line numberDiff line change
@@ -97,4 +97,36 @@ var zipResultEleEle = zipResult[0][0]; // string
9797
>0 : Symbol(0)
9898
>0 : Symbol(0)
9999

100+
// #33559 and #33752
101+
102+
declare function f1<T1, T2>(values: [T1[], T2[]]): T1;
103+
>f1 : Symbol(f1, Decl(typeInferenceWithTupleType.ts, 22, 38))
104+
>T1 : Symbol(T1, Decl(typeInferenceWithTupleType.ts, 26, 20))
105+
>T2 : Symbol(T2, Decl(typeInferenceWithTupleType.ts, 26, 23))
106+
>values : Symbol(values, Decl(typeInferenceWithTupleType.ts, 26, 28))
107+
>T1 : Symbol(T1, Decl(typeInferenceWithTupleType.ts, 26, 20))
108+
>T2 : Symbol(T2, Decl(typeInferenceWithTupleType.ts, 26, 23))
109+
>T1 : Symbol(T1, Decl(typeInferenceWithTupleType.ts, 26, 20))
110+
111+
declare function f2<T1, T2>(values: readonly [T1[], T2[]]): T1;
112+
>f2 : Symbol(f2, Decl(typeInferenceWithTupleType.ts, 26, 54))
113+
>T1 : Symbol(T1, Decl(typeInferenceWithTupleType.ts, 27, 20))
114+
>T2 : Symbol(T2, Decl(typeInferenceWithTupleType.ts, 27, 23))
115+
>values : Symbol(values, Decl(typeInferenceWithTupleType.ts, 27, 28))
116+
>T1 : Symbol(T1, Decl(typeInferenceWithTupleType.ts, 27, 20))
117+
>T2 : Symbol(T2, Decl(typeInferenceWithTupleType.ts, 27, 23))
118+
>T1 : Symbol(T1, Decl(typeInferenceWithTupleType.ts, 27, 20))
119+
120+
let expected: "a";
121+
>expected : Symbol(expected, Decl(typeInferenceWithTupleType.ts, 29, 3))
122+
123+
expected = f1(undefined as ["a"[], "b"[]]);
124+
>expected : Symbol(expected, Decl(typeInferenceWithTupleType.ts, 29, 3))
125+
>f1 : Symbol(f1, Decl(typeInferenceWithTupleType.ts, 22, 38))
126+
>undefined : Symbol(undefined)
127+
128+
expected = f2(undefined as ["a"[], "b"[]]);
129+
>expected : Symbol(expected, Decl(typeInferenceWithTupleType.ts, 29, 3))
130+
>f2 : Symbol(f2, Decl(typeInferenceWithTupleType.ts, 26, 54))
131+
>undefined : Symbol(undefined)
100132

tests/baselines/reference/typeInferenceWithTupleType.types

+28
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,32 @@ var zipResultEleEle = zipResult[0][0]; // string
109109
>0 : 0
110110
>0 : 0
111111

112+
// #33559 and #33752
113+
114+
declare function f1<T1, T2>(values: [T1[], T2[]]): T1;
115+
>f1 : <T1, T2>(values: [T1[], T2[]]) => T1
116+
>values : [T1[], T2[]]
117+
118+
declare function f2<T1, T2>(values: readonly [T1[], T2[]]): T1;
119+
>f2 : <T1, T2>(values: readonly [T1[], T2[]]) => T1
120+
>values : readonly [T1[], T2[]]
121+
122+
let expected: "a";
123+
>expected : "a"
124+
125+
expected = f1(undefined as ["a"[], "b"[]]);
126+
>expected = f1(undefined as ["a"[], "b"[]]) : "a"
127+
>expected : "a"
128+
>f1(undefined as ["a"[], "b"[]]) : "a"
129+
>f1 : <T1, T2>(values: [T1[], T2[]]) => T1
130+
>undefined as ["a"[], "b"[]] : ["a"[], "b"[]]
131+
>undefined : undefined
132+
133+
expected = f2(undefined as ["a"[], "b"[]]);
134+
>expected = f2(undefined as ["a"[], "b"[]]) : "a"
135+
>expected : "a"
136+
>f2(undefined as ["a"[], "b"[]]) : "a"
137+
>f2 : <T1, T2>(values: readonly [T1[], T2[]]) => T1
138+
>undefined as ["a"[], "b"[]] : ["a"[], "b"[]]
139+
>undefined : undefined
112140

tests/cases/compiler/correctOrderOfPromiseMethod.ts

+5-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ async function countEverything(): Promise<number> {
1717
const [resultA, resultB] = await Promise.all([
1818
providerA(),
1919
providerB(),
20-
] as const);
20+
]);
2121

2222
const dataA: A[] = resultA;
2323
const dataB: B[] = resultB;
@@ -26,3 +26,7 @@ async function countEverything(): Promise<number> {
2626
}
2727
return 0;
2828
}
29+
30+
// #31179
31+
32+
const expected: Promise<["a", "b", "c"]> = Promise.all(undefined as readonly ["a", "b", "c"]);

0 commit comments

Comments
 (0)