Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 13 additions & 9 deletions internal/checker/inference.go
Original file line number Diff line number Diff line change
Expand Up @@ -712,9 +712,11 @@ func (c *Checker) inferFromObjectTypes(n *InferenceState, source *Type, target *
constraint := c.getBaseConstraintOfType(info.typeParameter)
if constraint != nil && isTupleType(constraint) && constraint.TargetTupleType().combinedFlags&ElementFlagsVariable == 0 {
impliedArity := constraint.TargetTupleType().fixedLength
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixedLength still includes optional elements. In those cases, the checker could assume it needed more fixed source elements even when fewer were guaranteed, and that led to invalid slice math and crashing

c.inferFromTypes(n, c.sliceTupleType(source, startLength, sourceArity-(startLength+impliedArity)), elementTypes[startLength])
if restType := c.getElementTypeOfSliceOfTupleType(source, startLength+impliedArity, endLength, false, false); restType != nil {
c.inferFromTypes(n, restType, elementTypes[startLength+1])
if startLength+impliedArity <= source.TargetTupleType().fixedLength {
c.inferFromTypes(n, c.sliceTupleType(source, startLength, sourceArity-(startLength+impliedArity)), elementTypes[startLength])
if restType := c.getElementTypeOfSliceOfTupleType(source, startLength+impliedArity, endLength, false, false); restType != nil {
c.inferFromTypes(n, restType, elementTypes[startLength+1])
}
}
}
}
Expand All @@ -725,13 +727,15 @@ func (c *Checker) inferFromObjectTypes(n *InferenceState, source *Type, target *
constraint := c.getBaseConstraintOfType(info.typeParameter)
if constraint != nil && isTupleType(constraint) && constraint.TargetTupleType().combinedFlags&ElementFlagsVariable == 0 {
impliedArity := constraint.TargetTupleType().fixedLength
endIndex := sourceArity - getEndElementCount(target.TargetTupleType(), ElementFlagsFixed)
startIndex := endIndex - impliedArity
trailingSlice := c.createTupleTypeEx(c.getTypeArguments(source)[startIndex:endIndex], source.TargetTupleType().elementInfos[startIndex:endIndex], false /*readonly*/)
if restType := c.getElementTypeOfSliceOfTupleType(source, startLength, endLength+impliedArity, false, false); restType != nil {
c.inferFromTypes(n, restType, elementTypes[startLength])
if endLength+impliedArity <= getEndElementCount(source.TargetTupleType(), ElementFlagsFixed) {
endIndex := sourceArity - getEndElementCount(target.TargetTupleType(), ElementFlagsFixed)
startIndex := endIndex - impliedArity
trailingSlice := c.createTupleTypeEx(c.getTypeArguments(source)[startIndex:endIndex], source.TargetTupleType().elementInfos[startIndex:endIndex], false /*readonly*/)
if restType := c.getElementTypeOfSliceOfTupleType(source, startLength, endLength+impliedArity, false, false); restType != nil {
c.inferFromTypes(n, restType, elementTypes[startLength])
}
c.inferFromTypes(n, trailingSlice, elementTypes[startLength+1])
}
c.inferFromTypes(n, trailingSlice, elementTypes[startLength+1])
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
inferTypesWithFixedTupleExtendsAtVariadicPosition2.ts(112,27): error TS1257: A required element cannot follow an optional element.
inferTypesWithFixedTupleExtendsAtVariadicPosition2.ts(168,27): error TS1257: A required element cannot follow an optional element.


==== inferTypesWithFixedTupleExtendsAtVariadicPosition2.ts (2 errors) ====
// repro #51138

type SubTup2FixedLength<T extends unknown[]> = T extends [
...infer B extends [any, any],
any
]
? B
: never;

type SubTup2FixedLengthTest2 = SubTup2FixedLength<[a: 0]>;

type SubTup2Variadic<T extends unknown[]> = T extends [
...infer B extends [any, any],
...any
]
? B
: never;

type SubTup2VariadicTest3 = SubTup2Variadic<[a: 0, ...b: 1[]]>;
type SubTup2VariadicTest4 = SubTup2Variadic<[...a: 0[]]>;
type SubTup2VariadicTest5 = SubTup2Variadic<[a: 0, b: 1]>;

type SubTup2VariadicAndRest<T extends unknown[]> = T extends [
...infer B extends [any, any],
...(infer C)[]
]
? [...B, ...[C]]
: never;

type SubTup2VariadicAndRestTest2 = SubTup2VariadicAndRest<[a: 0, ...b: 1[]]>;
type SubTup2VariadicAndRestTest3 = SubTup2VariadicAndRest<[...a: 0[]]>;
type SubTup2VariadicAndRestTest4 = SubTup2VariadicAndRest<[a: 0, b: 1]>;

type SubTup2TrailingVariadic<T extends unknown[]> = T extends [
...any,
...infer B extends [any, any],
]
? B
: never;

type SubTup2TrailingVariadicTest3 = SubTup2TrailingVariadic<[...a: 0[], b: 1]>;
type SubTup2TrailingVariadicTest4 = SubTup2TrailingVariadic<[...a: 0[]]>;
type SubTup2TrailingVariadicTest5 = SubTup2TrailingVariadic<[b: 1, c: 2]>;

type SubTup2RestAndTrailingVariadic2<T extends unknown[]> = T extends [
...(infer C)[],
...infer B extends [any, any],
]
? [C, ...B]
: never;

type SubTup2RestAndTrailingVariadic2Test2 = SubTup2RestAndTrailingVariadic2<[...a: 0[], b: 1]>;
type SubTup2RestAndTrailingVariadic2Test3 = SubTup2RestAndTrailingVariadic2<[...a: 0[]]>;
type SubTup2RestAndTrailingVariadic2Test4 = SubTup2RestAndTrailingVariadic2<[b: 1, c: 2]>;

type SubTup2VariadicWithLeadingFixedElements<T extends unknown[]> = T extends [
any,
...infer B extends [any, any],
...any
]
? B
: never;

type SubTup2VariadicWithLeadingFixedElementsTest3 = SubTup2VariadicWithLeadingFixedElements<[a: 0, b: 1, ...c: 2[]]>;
type SubTup2VariadicWithLeadingFixedElementsTest4 = SubTup2VariadicWithLeadingFixedElements<[a: 0, ...b: 1[]]>;
type SubTup2VariadicWithLeadingFixedElementsTest5 = SubTup2VariadicWithLeadingFixedElements<[...a: 0[]]>;

type SubTup2VariadicWithLeadingFixedElements2<T extends unknown[]> = T extends [
any,
any,
...infer B extends [any],
...any
]
? B
: never;

type SubTup2VariadicWithLeadingFixedElements2Test = SubTup2VariadicWithLeadingFixedElements2<[a: 0, b: 1, c: 2, ...d: 3[]]>;
type SubTup2VariadicWithLeadingFixedElements2Test2 = SubTup2VariadicWithLeadingFixedElements2<[a: 0, b: 1, c: 2, d: 3, ...e: 4[]]>;
type SubTup2VariadicWithLeadingFixedElements2Test3 = SubTup2VariadicWithLeadingFixedElements2<[a: 0, b: 1, ...c: 2[]]>;
type SubTup2VariadicWithLeadingFixedElements2Test4 = SubTup2VariadicWithLeadingFixedElements2<[a: 0, ...b: 1[]]>;
type SubTup2VariadicWithLeadingFixedElements2Test5 = SubTup2VariadicWithLeadingFixedElements2<[...a: 0[]]>;

type SubTup2VariadicWithLeadingFixedElements3<T extends unknown[]> = T extends [
any,
...infer B extends [any, any],
...(infer C)[]
]
? [B, C]
: never;

type SubTup2VariadicWithLeadingFixedElements3Test = SubTup2VariadicWithLeadingFixedElements3<[a: 0, b: 1, c: 2, d: 3, ...e: 4[]]>;
type SubTup2VariadicWithLeadingFixedElements3Test2 = SubTup2VariadicWithLeadingFixedElements3<[a: 0, b: 1, c: 2, ...d: 3[]]>;
type SubTup2VariadicWithLeadingFixedElements3Test3 = SubTup2VariadicWithLeadingFixedElements3<[a: 0, b: 1, ...c: 2[]]>;
type SubTup2VariadicWithLeadingFixedElements3Test4 = SubTup2VariadicWithLeadingFixedElements3<[a: 0, ...b: 1[]]>;
type SubTup2VariadicWithLeadingFixedElements3Test5 = SubTup2VariadicWithLeadingFixedElements3<[...a: 0[]]>;
type SubTup2VariadicWithLeadingFixedElements3Test6 = SubTup2VariadicWithLeadingFixedElements3<[a: 0, b: 1, c: 2]>;

type SubTup2VariadicWithTrailingOptionalElement<T extends unknown[]> = T extends [
...infer B extends [0, 1?],
...any
]
? B
: never;

type SubTup2VariadicWithTrailingOptionalElementTest = SubTup2VariadicWithTrailingOptionalElement<[a: 0]>;
type SubTup2VariadicWithTrailingOptionalElementTest2 = SubTup2VariadicWithTrailingOptionalElement<[a: 0, b: 1]>;
type SubTup2VariadicWithTrailingOptionalElementTest3 = SubTup2VariadicWithTrailingOptionalElement<[a: 0, b: 1, c: 2]>;
type SubTup2VariadicWithTrailingOptionalElementTest4 = SubTup2VariadicWithTrailingOptionalElement<[a: 0, ...b: 1[]]>;
type SubTup2VariadicWithTrailingOptionalElementTest5 = SubTup2VariadicWithTrailingOptionalElement<[...a: 0[]]>;

type SubTup2VariadicWithLeadingOptionalElement<T extends unknown[]> = T extends [
...infer B extends [0?, 1],
~
!!! error TS1257: A required element cannot follow an optional element.
...any
]
? B
: never;

type SubTup2VariadicWithLeadingOptionalElementTest = SubTup2VariadicWithLeadingOptionalElement<[b: 1]>;
type SubTup2VariadicWithLeadingOptionalElementTest2 = SubTup2VariadicWithLeadingOptionalElement<[a: 0, b: 1]>;
type SubTup2VariadicWithLeadingOptionalElementTest3 = SubTup2VariadicWithLeadingOptionalElement<[a: 0, b: 1, c: 2]>;
type SubTup2VariadicWithLeadingOptionalElementTest4 = SubTup2VariadicWithLeadingOptionalElement<[a: 0, ...b: 1[]]>;
type SubTup2VariadicWithLeadingOptionalElementTest5 = SubTup2VariadicWithLeadingOptionalElement<[...a: 1[]]>;

type SubTup2TrailingVariadicWithTrailingFixedElements<T extends unknown[]> = T extends [
...any,
...infer B extends [any, any],
any,
]
? B
: never;

type SubTup2TrailingVariadicWithTrailingFixedElementsTest3 = SubTup2TrailingVariadicWithTrailingFixedElements<[...a: 0[], b: 1, c: 2]>;
type SubTup2TrailingVariadicWithTrailingFixedElementsTest4 = SubTup2TrailingVariadicWithTrailingFixedElements<[...a: 0[], b: 1]>;
type SubTup2TrailingVariadicWithTrailingFixedElementsTest5 = SubTup2TrailingVariadicWithTrailingFixedElements<[...a: 0[]]>;

type SubTup2TrailingVariadicWithTrailingFixedElements2<T extends unknown[]> = T extends [
...any,
...infer B extends [any],
any,
any,
]
? B
: never;

type SubTup2TrailingVariadicWithTrailingFixedElements2Test = SubTup2TrailingVariadicWithTrailingFixedElements2<[...a: 0[], b: 1, c: 2, d: 3]>;
type SubTup2TrailingVariadicWithTrailingFixedElements2Test2 = SubTup2TrailingVariadicWithTrailingFixedElements2<[...a: 0[], b: 1, c: 2, d: 3, e: 4]>;
type SubTup2TrailingVariadicWithTrailingFixedElements2Test3 = SubTup2TrailingVariadicWithTrailingFixedElements2<[...a: 0[], b: 1, c: 2]>;
type SubTup2TrailingVariadicWithTrailingFixedElements2Test4 = SubTup2TrailingVariadicWithTrailingFixedElements2<[...a: 0[], b: 1]>;
type SubTup2TrailingVariadicWithTrailingFixedElements2Test5 = SubTup2TrailingVariadicWithTrailingFixedElements2<[...a: 0[]]>;

type SubTup2TrailingVariadicWithTrailingFixedElements3<T extends unknown[]> = T extends [
...(infer C)[],
...infer B extends [any, any],
any,
]
? [C, B]
: never;

type SubTup2TrailingVariadicWithTrailingFixedElements3Test = SubTup2TrailingVariadicWithTrailingFixedElements3<[...a: 0[], b: 1, c: 2, d: 3, e: 4]>;
type SubTup2TrailingVariadicWithTrailingFixedElements3Test2 = SubTup2TrailingVariadicWithTrailingFixedElements3<[...a: 0[], b: 1, c: 2, d: 3]>;
type SubTup2TrailingVariadicWithTrailingFixedElements3Test3 = SubTup2TrailingVariadicWithTrailingFixedElements3<[...a: 0[], b: 1, c: 2]>;
type SubTup2TrailingVariadicWithTrailingFixedElements3Test4 = SubTup2TrailingVariadicWithTrailingFixedElements3<[...a: 0[], b: 1]>;
type SubTup2TrailingVariadicWithTrailingFixedElements3Test5 = SubTup2TrailingVariadicWithTrailingFixedElements3<[...a: 0[]]>;
type SubTup2TrailingVariadicWithTrailingFixedElements3Test6 = SubTup2TrailingVariadicWithTrailingFixedElements3<[b: 1, c: 2, d: 3]>;

type SubTup2TrailingVariadicWithLeadingOptionalElement<T extends unknown[]> = T extends [
...any,
...infer B extends [0?, 1],
~
!!! error TS1257: A required element cannot follow an optional element.
]
? B
: never;

type SubTup2TrailingVariadicWithLeadingOptionalElementTest = SubTup2TrailingVariadicWithLeadingOptionalElement<[b: 1]>;
type SubTup2TrailingVariadicWithLeadingOptionalElementTest2 = SubTup2TrailingVariadicWithLeadingOptionalElement<[a: 0, b: 1]>;
type SubTup2TrailingVariadicWithLeadingOptionalElementTest3 = SubTup2TrailingVariadicWithLeadingOptionalElement<[a: 2, b: 0, c: 1]>;
type SubTup2TrailingVariadicWithLeadingOptionalElementTest4 = SubTup2TrailingVariadicWithLeadingOptionalElement<[...a: 0[], b: 1]>;
type SubTup2TrailingVariadicWithLeadingOptionalElementTest5 = SubTup2TrailingVariadicWithLeadingOptionalElement<[...a: 1[]]>;

type SubTup2TrailingVariadicWithTrailingOptionalElement<T extends unknown[]> = T extends [
...any,
...infer B extends [0, 1?],
]
? B
: never;

type SubTup2TrailingVariadicWithTrailingOptionalElementTest = SubTup2TrailingVariadicWithTrailingOptionalElement<[a: 0]>;
type SubTup2TrailingVariadicWithTrailingOptionalElementTest2 = SubTup2TrailingVariadicWithTrailingOptionalElement<[a: 0, b: 1]>;
type SubTup2TrailingVariadicWithTrailingOptionalElementTest3 = SubTup2TrailingVariadicWithTrailingOptionalElement<[a: 2, b: 0, c: 1]>;
type SubTup2TrailingVariadicWithTrailingOptionalElementTest4 = SubTup2TrailingVariadicWithTrailingOptionalElement<[...a: 0[]]>;
type SubTup2TrailingVariadicWithTrailingOptionalElementTest5 = SubTup2TrailingVariadicWithTrailingOptionalElement<[...a: 0[], b: 1]>;

Loading
Loading