Skip to content

Commit 469ba1f

Browse files
조용진조용진
authored andcommitted
Fix crash when inferring from tuple with middle rest and trailing variadic elements
When `getElementTypeOfSliceOfTupleType` returns `undefined` (because the implied arity from the variadic constraint consumes the entire source tuple), the result was passed directly to `inferFromTypes` via a non-null assertion, causing a `TypeError: Cannot read properties of undefined (reading 'aliasSymbol')` crash. Add null checks before calling `inferFromTypes` in both the `[...T, ...rest]` and `[...rest, ...T]` inference branches, consistent with the existing pattern used in the single-rest-element branch. Fixes #63005
1 parent 4f7b417 commit 469ba1f

File tree

4 files changed

+56
-3
lines changed

4 files changed

+56
-3
lines changed

src/compiler/checker.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27422,7 +27422,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2742227422
if (constraint && isTupleType(constraint) && !(constraint.target.combinedFlags & ElementFlags.Variable)) {
2742327423
const impliedArity = constraint.target.fixedLength;
2742427424
inferFromTypes(sliceTupleType(source, startLength, sourceArity - (startLength + impliedArity)), elementTypes[startLength]);
27425-
inferFromTypes(getElementTypeOfSliceOfTupleType(source, startLength + impliedArity, endLength)!, elementTypes[startLength + 1]);
27425+
const restType = getElementTypeOfSliceOfTupleType(source, startLength + impliedArity, endLength);
27426+
if (restType) {
27427+
inferFromTypes(restType, elementTypes[startLength + 1]);
27428+
}
2742627429
}
2742727430
}
2742827431
else if (elementFlags[startLength] & ElementFlags.Rest && elementFlags[startLength + 1] & ElementFlags.Variadic) {
@@ -27435,8 +27438,10 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
2743527438
const endIndex = sourceArity - getEndElementCount(target.target, ElementFlags.Fixed);
2743627439
const startIndex = endIndex - impliedArity;
2743727440
const trailingSlice = createTupleType(getTypeArguments(source).slice(startIndex, endIndex), source.target.elementFlags.slice(startIndex, endIndex), /*readonly*/ false, source.target.labeledElementDeclarations && source.target.labeledElementDeclarations.slice(startIndex, endIndex));
27438-
27439-
inferFromTypes(getElementTypeOfSliceOfTupleType(source, startLength, endLength + impliedArity)!, elementTypes[startLength]);
27441+
const restType = getElementTypeOfSliceOfTupleType(source, startLength, endLength + impliedArity);
27442+
if (restType) {
27443+
inferFromTypes(restType, elementTypes[startLength]);
27444+
}
2744027445
inferFromTypes(trailingSlice, elementTypes[startLength + 1]);
2744127446
}
2744227447
}

tests/baselines/reference/inferTypesWithFixedTupleExtendsAtVariadicPosition.symbols

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,3 +160,26 @@ type SubTup2TrailingVariadicWithTrailingFixedElementsTest2 = SubTup2TrailingVari
160160
>SubTup2TrailingVariadicWithTrailingFixedElementsTest2 : Symbol(SubTup2TrailingVariadicWithTrailingFixedElementsTest2, Decl(inferTypesWithFixedTupleExtendsAtVariadicPosition.ts, 68, 140))
161161
>SubTup2TrailingVariadicWithTrailingFixedElements : Symbol(SubTup2TrailingVariadicWithTrailingFixedElements, Decl(inferTypesWithFixedTupleExtendsAtVariadicPosition.ts, 58, 129))
162162

163+
// repro #63005 - should not crash when implied arity consumes entire source tuple
164+
type SubTup2RestAndTrailingVariadic3<T extends unknown[]> = T extends [
165+
>SubTup2RestAndTrailingVariadic3 : Symbol(SubTup2RestAndTrailingVariadic3, Decl(inferTypesWithFixedTupleExtendsAtVariadicPosition.ts, 69, 147))
166+
>T : Symbol(T, Decl(inferTypesWithFixedTupleExtendsAtVariadicPosition.ts, 72, 37))
167+
>T : Symbol(T, Decl(inferTypesWithFixedTupleExtendsAtVariadicPosition.ts, 72, 37))
168+
169+
...(infer C)[],
170+
>C : Symbol(C, Decl(inferTypesWithFixedTupleExtendsAtVariadicPosition.ts, 73, 13))
171+
172+
...infer B extends [any, any, any]
173+
>B : Symbol(B, Decl(inferTypesWithFixedTupleExtendsAtVariadicPosition.ts, 74, 12))
174+
175+
]
176+
? [C, ...B]
177+
>C : Symbol(C, Decl(inferTypesWithFixedTupleExtendsAtVariadicPosition.ts, 73, 13))
178+
>B : Symbol(B, Decl(inferTypesWithFixedTupleExtendsAtVariadicPosition.ts, 74, 12))
179+
180+
: never;
181+
182+
type SubTup2RestAndTrailingVariadic3Test = SubTup2RestAndTrailingVariadic3<[...a: 0[], b: 1, c: 2]>;
183+
>SubTup2RestAndTrailingVariadic3Test : Symbol(SubTup2RestAndTrailingVariadic3Test, Decl(inferTypesWithFixedTupleExtendsAtVariadicPosition.ts, 77, 12))
184+
>SubTup2RestAndTrailingVariadic3 : Symbol(SubTup2RestAndTrailingVariadic3, Decl(inferTypesWithFixedTupleExtendsAtVariadicPosition.ts, 69, 147))
185+

tests/baselines/reference/inferTypesWithFixedTupleExtendsAtVariadicPosition.types

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,3 +119,18 @@ type SubTup2TrailingVariadicWithTrailingFixedElementsTest2 = SubTup2TrailingVari
119119
>SubTup2TrailingVariadicWithTrailingFixedElementsTest2 : [c: 2, d: 3]
120120
> : ^^^^^^^^^^^^
121121

122+
// repro #63005 - should not crash when implied arity consumes entire source tuple
123+
type SubTup2RestAndTrailingVariadic3<T extends unknown[]> = T extends [
124+
>SubTup2RestAndTrailingVariadic3 : SubTup2RestAndTrailingVariadic3<T>
125+
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
126+
127+
...(infer C)[],
128+
...infer B extends [any, any, any]
129+
]
130+
? [C, ...B]
131+
: never;
132+
133+
type SubTup2RestAndTrailingVariadic3Test = SubTup2RestAndTrailingVariadic3<[...a: 0[], b: 1, c: 2]>;
134+
>SubTup2RestAndTrailingVariadic3Test : never
135+
> : ^^^^^
136+

tests/cases/compiler/inferTypesWithFixedTupleExtendsAtVariadicPosition.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,13 @@ type SubTup2TrailingVariadicWithTrailingFixedElements<T extends unknown[]> = T e
7272

7373
type SubTup2TrailingVariadicWithTrailingFixedElementsTest = SubTup2TrailingVariadicWithTrailingFixedElements<[...a: 0[], b: 1, c: 2, d: 3]>;
7474
type SubTup2TrailingVariadicWithTrailingFixedElementsTest2 = SubTup2TrailingVariadicWithTrailingFixedElements<[...a: 0[], b: 1, c: 2, d: 3, e: 4]>;
75+
76+
// repro #63005 - should not crash when implied arity consumes entire source tuple
77+
type SubTup2RestAndTrailingVariadic3<T extends unknown[]> = T extends [
78+
...(infer C)[],
79+
...infer B extends [any, any, any]
80+
]
81+
? [C, ...B]
82+
: never;
83+
84+
type SubTup2RestAndTrailingVariadic3Test = SubTup2RestAndTrailingVariadic3<[...a: 0[], b: 1, c: 2]>;

0 commit comments

Comments
 (0)