From ab0eb5c0cde9343ba7627d993d26f1b98fd323ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Burzy=C5=84ski?= Date: Sat, 6 Aug 2022 17:34:08 +0200 Subject: [PATCH] Fixed the issue with some longer variadic tuples with `any` rest being incorrectly assignable to shorter variadic tuples --- src/compiler/checker.ts | 41 +++-- src/compiler/types.ts | 9 +- .../reference/api/tsserverlibrary.d.ts | 3 + tests/baselines/reference/api/typescript.d.ts | 3 + .../reference/restTupleElements1.errors.txt | 12 +- .../reference/variadicTuples2.errors.txt | 71 +++---- tests/baselines/reference/variadicTuples2.js | 9 +- .../reference/variadicTuples2.symbols | 174 +++++++++--------- .../baselines/reference/variadicTuples2.types | 10 +- .../types/tuple/variadicTuples2.ts | 6 +- 10 files changed, 191 insertions(+), 147 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d1c202c8bde8e..eedb07b6d6421 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -20275,28 +20275,35 @@ namespace ts { } const sourceTypeArguments = getTypeArguments(source); const targetTypeArguments = getTypeArguments(target); - const startCount = Math.min(isTupleType(source) ? getStartElementCount(source.target, ElementFlags.NonRest) : 0, getStartElementCount(target.target, ElementFlags.NonRest)); - const endCount = Math.min(isTupleType(source) ? getEndElementCount(source.target, ElementFlags.NonRest) : 0, targetRestFlag ? getEndElementCount(target.target, ElementFlags.NonRest) : 0); + const targetStartCount = getStartElementCount(target.target, ElementFlags.NonRest); + const targetEndCount = getEndElementCount(target.target, ElementFlags.NonRest); + const targetHasRestElement = target.target.hasRestElement; let canExcludeDiscriminants = !!excludedProperties; - for (let i = 0; i < targetArity; i++) { - const sourceIndex = i < targetArity - endCount ? i : i + sourceArity - targetArity; - const sourceFlags = isTupleType(source) && (i < startCount || i >= targetArity - endCount) ? source.target.elementFlags[sourceIndex] : ElementFlags.Rest; - const targetFlags = target.target.elementFlags[i]; + for (let sourcePosition = 0; sourcePosition < sourceArity; sourcePosition++) { + const sourceFlags = isTupleType(source) ? source.target.elementFlags[sourcePosition] : ElementFlags.Rest; + const sourcePositionFromEnd = sourceArity - 1 - sourcePosition; + + const targetPosition = targetHasRestElement && sourcePosition >= targetStartCount + ? targetArity - 1 - Math.min(sourcePositionFromEnd, targetEndCount) + : sourcePosition; + + const targetFlags = target.target.elementFlags[targetPosition]; + if (targetFlags & ElementFlags.Variadic && !(sourceFlags & ElementFlags.Variadic)) { if (reportErrors) { - reportError(Diagnostics.Source_provides_no_match_for_variadic_element_at_position_0_in_target, i); + reportError(Diagnostics.Source_provides_no_match_for_variadic_element_at_position_0_in_target, targetPosition); } return Ternary.False; } if (sourceFlags & ElementFlags.Variadic && !(targetFlags & ElementFlags.Variable)) { if (reportErrors) { - reportError(Diagnostics.Variadic_element_at_position_0_in_source_does_not_match_element_at_position_1_in_target, sourceIndex, i); + reportError(Diagnostics.Variadic_element_at_position_0_in_source_does_not_match_element_at_position_1_in_target, sourcePosition, targetPosition); } return Ternary.False; } if (targetFlags & ElementFlags.Required && !(sourceFlags & ElementFlags.Required)) { if (reportErrors) { - reportError(Diagnostics.Source_provides_no_match_for_required_element_at_position_0_in_target, i); + reportError(Diagnostics.Source_provides_no_match_for_required_element_at_position_0_in_target, targetPosition); } return Ternary.False; } @@ -20305,24 +20312,24 @@ namespace ts { if (sourceFlags & ElementFlags.Variable || targetFlags & ElementFlags.Variable) { canExcludeDiscriminants = false; } - if (canExcludeDiscriminants && excludedProperties?.has(("" + i) as __String)) { + if (canExcludeDiscriminants && excludedProperties?.has(("" + sourcePosition) as __String)) { continue; } } - const sourceType = !isTupleType(source) ? sourceTypeArguments[0] : - i < startCount || i >= targetArity - endCount ? removeMissingType(sourceTypeArguments[sourceIndex], !!(sourceFlags & targetFlags & ElementFlags.Optional)) : - getElementTypeOfSliceOfTupleType(source, startCount, endCount) || neverType; - const targetType = targetTypeArguments[i]; + + const sourceType = removeMissingType(sourceTypeArguments[sourcePosition], !!(sourceFlags & targetFlags & ElementFlags.Optional)); + const targetType = targetTypeArguments[targetPosition]; + const targetCheckType = sourceFlags & ElementFlags.Variadic && targetFlags & ElementFlags.Rest ? createArrayType(targetType) : removeMissingType(targetType, !!(targetFlags & ElementFlags.Optional)); const related = isRelatedTo(sourceType, targetCheckType, RecursionFlags.Both, reportErrors, /*headMessage*/ undefined, intersectionState); if (!related) { if (reportErrors && (targetArity > 1 || sourceArity > 1)) { - if (i < startCount || i >= targetArity - endCount || sourceArity - startCount - endCount === 1) { - reportIncompatibleError(Diagnostics.Type_at_position_0_in_source_is_not_compatible_with_type_at_position_1_in_target, sourceIndex, i); + if (targetHasRestElement && sourcePosition >= targetStartCount && sourcePositionFromEnd >= targetEndCount && targetStartCount !== sourceArity - targetEndCount - 1) { + reportIncompatibleError(Diagnostics.Type_at_positions_0_through_1_in_source_is_not_compatible_with_type_at_position_2_in_target, targetStartCount, sourceArity - targetEndCount - 1, targetPosition); } else { - reportIncompatibleError(Diagnostics.Type_at_positions_0_through_1_in_source_is_not_compatible_with_type_at_position_2_in_target, startCount, sourceArity - endCount - 1, i); + reportIncompatibleError(Diagnostics.Type_at_position_0_in_source_is_not_compatible_with_type_at_position_1_in_target, sourcePosition, targetPosition); } } return Ternary.False; diff --git a/src/compiler/types.ts b/src/compiler/types.ts index f93f36c369157..71d26102d8d4b 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -5691,9 +5691,12 @@ namespace ts { export interface TupleType extends GenericType { elementFlags: readonly ElementFlags[]; - minLength: number; // Number of required or variadic elements - fixedLength: number; // Number of initial required or optional elements - hasRestElement: boolean; // True if tuple has any rest or variadic elements + /** Number of required or variadic elements */ + minLength: number; + /** Number of initial required or optional elements */ + fixedLength: number; + /** True if tuple has any rest or variadic elements */ + hasRestElement: boolean; combinedFlags: ElementFlags; readonly: boolean; labeledElementDeclarations?: readonly (NamedTupleMember | ParameterDeclaration)[]; diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index bbc5c38476cdd..73e4a79e37c67 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -2766,8 +2766,11 @@ declare namespace ts { } export interface TupleType extends GenericType { elementFlags: readonly ElementFlags[]; + /** Number of required or variadic elements */ minLength: number; + /** Number of initial required or optional elements */ fixedLength: number; + /** True if tuple has any rest or variadic elements */ hasRestElement: boolean; combinedFlags: ElementFlags; readonly: boolean; diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index f9e5f2d0bdebf..a6351d25867aa 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -2766,8 +2766,11 @@ declare namespace ts { } export interface TupleType extends GenericType { elementFlags: readonly ElementFlags[]; + /** Number of required or variadic elements */ minLength: number; + /** Number of initial required or optional elements */ fixedLength: number; + /** True if tuple has any rest or variadic elements */ hasRestElement: boolean; combinedFlags: ElementFlags; readonly: boolean; diff --git a/tests/baselines/reference/restTupleElements1.errors.txt b/tests/baselines/reference/restTupleElements1.errors.txt index c96ac5fb20c0c..896639cb8e626 100644 --- a/tests/baselines/reference/restTupleElements1.errors.txt +++ b/tests/baselines/reference/restTupleElements1.errors.txt @@ -18,12 +18,10 @@ tests/cases/conformance/types/tuple/restTupleElements1.ts(33,31): error TS2344: Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/tuple/restTupleElements1.ts(34,31): error TS2344: Type '[number, number, string]' does not satisfy the constraint '[number, ...number[]]'. Type at positions 1 through 2 in source is not compatible with type at position 1 in target. - Type 'string | number' is not assignable to type 'number'. - Type 'string' is not assignable to type 'number'. + Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/tuple/restTupleElements1.ts(35,31): error TS2344: Type '[number, number, number, string]' does not satisfy the constraint '[number, ...number[]]'. Type at positions 1 through 3 in source is not compatible with type at position 1 in target. - Type 'string | number' is not assignable to type 'number'. - Type 'string' is not assignable to type 'number'. + Type 'string' is not assignable to type 'number'. tests/cases/conformance/types/tuple/restTupleElements1.ts(59,4): error TS2345: Argument of type '[]' is not assignable to parameter of type '[unknown, ...unknown[]]'. Source has 0 element(s) but target requires 1. @@ -94,14 +92,12 @@ tests/cases/conformance/types/tuple/restTupleElements1.ts(59,4): error TS2345: A ~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2344: Type '[number, number, string]' does not satisfy the constraint '[number, ...number[]]'. !!! error TS2344: Type at positions 1 through 2 in source is not compatible with type at position 1 in target. -!!! error TS2344: Type 'string | number' is not assignable to type 'number'. -!!! error TS2344: Type 'string' is not assignable to type 'number'. +!!! error TS2344: Type 'string' is not assignable to type 'number'. assign<[number, ...number[]], [number, number, number, string]>(); // Error ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ !!! error TS2344: Type '[number, number, number, string]' does not satisfy the constraint '[number, ...number[]]'. !!! error TS2344: Type at positions 1 through 3 in source is not compatible with type at position 1 in target. -!!! error TS2344: Type 'string | number' is not assignable to type 'number'. -!!! error TS2344: Type 'string' is not assignable to type 'number'. +!!! error TS2344: Type 'string' is not assignable to type 'number'. type T20 = [number, string, ...boolean[]]; diff --git a/tests/baselines/reference/variadicTuples2.errors.txt b/tests/baselines/reference/variadicTuples2.errors.txt index dc7bcb061eee3..55cc6d5f66f4d 100644 --- a/tests/baselines/reference/variadicTuples2.errors.txt +++ b/tests/baselines/reference/variadicTuples2.errors.txt @@ -3,12 +3,10 @@ tests/cases/conformance/types/tuple/variadicTuples2.ts(8,34): error TS1266: An o tests/cases/conformance/types/tuple/variadicTuples2.ts(9,30): error TS1257: A required element cannot follow an optional element. tests/cases/conformance/types/tuple/variadicTuples2.ts(42,1): error TS2322: Type '[string, string, number, number]' is not assignable to type '[...string[], number]'. Type at positions 0 through 2 in source is not compatible with type at position 0 in target. - Type 'string | number' is not assignable to type 'string'. - Type 'number' is not assignable to type 'string'. + Type 'number' is not assignable to type 'string'. tests/cases/conformance/types/tuple/variadicTuples2.ts(48,5): error TS2345: Argument of type '["abc", "def", 5, 6]' is not assignable to parameter of type '[...strs: string[], num: number]'. Type at positions 0 through 2 in source is not compatible with type at position 0 in target. - Type 'string | number' is not assignable to type 'string'. - Type 'number' is not assignable to type 'string'. + Type 'number' is not assignable to type 'string'. tests/cases/conformance/types/tuple/variadicTuples2.ts(51,1): error TS2322: Type '[number]' is not assignable to type '[number, ...string[], number]'. Source has 1 element(s) but target requires 2. tests/cases/conformance/types/tuple/variadicTuples2.ts(53,1): error TS2322: Type '[number, number, number]' is not assignable to type '[number, ...string[], number]'. @@ -16,8 +14,7 @@ tests/cases/conformance/types/tuple/variadicTuples2.ts(53,1): error TS2322: Type Type 'number' is not assignable to type 'string'. tests/cases/conformance/types/tuple/variadicTuples2.ts(56,1): error TS2322: Type '[number, string, number, string]' is not assignable to type '[number, ...string[], number]'. Type at positions 1 through 2 in source is not compatible with type at position 1 in target. - Type 'string | number' is not assignable to type 'string'. - Type 'number' is not assignable to type 'string'. + Type 'number' is not assignable to type 'string'. tests/cases/conformance/types/tuple/variadicTuples2.ts(57,8): error TS2322: Type 'boolean' is not assignable to type 'number'. tests/cases/conformance/types/tuple/variadicTuples2.ts(58,1): error TS2322: Type '[number, string, string, boolean]' is not assignable to type '[number, ...string[], number]'. Type at position 3 in source is not compatible with type at position 2 in target. @@ -29,8 +26,7 @@ tests/cases/conformance/types/tuple/variadicTuples2.ts(63,8): error TS2345: Argu Type 'number' is not assignable to type 'string'. tests/cases/conformance/types/tuple/variadicTuples2.ts(66,8): error TS2345: Argument of type '["abc", 1, "def"]' is not assignable to parameter of type '[...strs: string[], n2: number]'. Type at positions 0 through 1 in source is not compatible with type at position 0 in target. - Type 'string | number' is not assignable to type 'string'. - Type 'number' is not assignable to type 'string'. + Type 'number' is not assignable to type 'string'. tests/cases/conformance/types/tuple/variadicTuples2.ts(67,5): error TS2345: Argument of type 'boolean' is not assignable to parameter of type 'number'. tests/cases/conformance/types/tuple/variadicTuples2.ts(68,8): error TS2345: Argument of type '["abc", "def", true]' is not assignable to parameter of type '[...strs: string[], n2: number]'. Type at position 2 in source is not compatible with type at position 1 in target. @@ -43,29 +39,33 @@ tests/cases/conformance/types/tuple/variadicTuples2.ts(73,5): error TS2322: Type Variadic element at position 1 in source does not match element at position 1 in target. tests/cases/conformance/types/tuple/variadicTuples2.ts(74,5): error TS2322: Type '[number, ...T]' is not assignable to type '[number, ...number[]]'. Type at position 1 in source is not compatible with type at position 1 in target. - Type 'T[number]' is not assignable to type 'number'. -tests/cases/conformance/types/tuple/variadicTuples2.ts(107,16): error TS2345: Argument of type '[1, 2, 3, 4]' is not assignable to parameter of type '[...number[], (...values: number[]) => void]'. + Type 'T' is not assignable to type 'number[]'. + Type 'unknown[]' is not assignable to type 'number[]'. + Type 'unknown' is not assignable to type 'number'. +tests/cases/conformance/types/tuple/variadicTuples2.ts(79,5): error TS2322: Type '[number, string, ...any[]]' is not assignable to type '[number, ...number[]]'. + Type at positions 1 through 2 in source is not compatible with type at position 1 in target. + Type 'string' is not assignable to type 'number'. +tests/cases/conformance/types/tuple/variadicTuples2.ts(111,16): error TS2345: Argument of type '[1, 2, 3, 4]' is not assignable to parameter of type '[...number[], (...values: number[]) => void]'. Type at position 3 in source is not compatible with type at position 1 in target. Type 'number' is not assignable to type '(...values: number[]) => void'. -tests/cases/conformance/types/tuple/variadicTuples2.ts(108,6): error TS2345: Argument of type 'string[]' is not assignable to parameter of type '[...string[], (...values: string[]) => void]'. +tests/cases/conformance/types/tuple/variadicTuples2.ts(112,6): error TS2345: Argument of type 'string[]' is not assignable to parameter of type '[...string[], (...values: string[]) => void]'. Source provides no match for required element at position 1 in target. -tests/cases/conformance/types/tuple/variadicTuples2.ts(111,5): error TS2345: Argument of type '[]' is not assignable to parameter of type '[...unknown[], unknown, unknown]'. +tests/cases/conformance/types/tuple/variadicTuples2.ts(115,5): error TS2345: Argument of type '[]' is not assignable to parameter of type '[...unknown[], unknown, unknown]'. Source has 0 element(s) but target requires 2. -tests/cases/conformance/types/tuple/variadicTuples2.ts(112,5): error TS2345: Argument of type '[number]' is not assignable to parameter of type '[...unknown[], unknown, unknown]'. +tests/cases/conformance/types/tuple/variadicTuples2.ts(116,5): error TS2345: Argument of type '[number]' is not assignable to parameter of type '[...unknown[], unknown, unknown]'. Source has 1 element(s) but target requires 2. -tests/cases/conformance/types/tuple/variadicTuples2.ts(117,5): error TS2345: Argument of type '[]' is not assignable to parameter of type '[unknown, ...unknown[], unknown]'. +tests/cases/conformance/types/tuple/variadicTuples2.ts(121,5): error TS2345: Argument of type '[]' is not assignable to parameter of type '[unknown, ...unknown[], unknown]'. Source has 0 element(s) but target requires 2. -tests/cases/conformance/types/tuple/variadicTuples2.ts(118,5): error TS2345: Argument of type '[number]' is not assignable to parameter of type '[unknown, ...unknown[], unknown]'. +tests/cases/conformance/types/tuple/variadicTuples2.ts(122,5): error TS2345: Argument of type '[number]' is not assignable to parameter of type '[unknown, ...unknown[], unknown]'. Source has 1 element(s) but target requires 2. -tests/cases/conformance/types/tuple/variadicTuples2.ts(128,16): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. -tests/cases/conformance/types/tuple/variadicTuples2.ts(129,16): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. -tests/cases/conformance/types/tuple/variadicTuples2.ts(130,25): error TS2345: Argument of type '["blah2", 1, 2, 3]' is not assignable to parameter of type '[...string[], number]'. +tests/cases/conformance/types/tuple/variadicTuples2.ts(132,16): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. +tests/cases/conformance/types/tuple/variadicTuples2.ts(133,16): error TS2345: Argument of type 'number' is not assignable to parameter of type 'string'. +tests/cases/conformance/types/tuple/variadicTuples2.ts(134,25): error TS2345: Argument of type '["blah2", 1, 2, 3]' is not assignable to parameter of type '[...string[], number]'. Type at positions 0 through 2 in source is not compatible with type at position 0 in target. - Type 'string | number' is not assignable to type 'string'. - Type 'number' is not assignable to type 'string'. + Type 'number' is not assignable to type 'string'. -==== tests/cases/conformance/types/tuple/variadicTuples2.ts (28 errors) ==== +==== tests/cases/conformance/types/tuple/variadicTuples2.ts (29 errors) ==== // Declarations type V00 = [number, ...string[]]; @@ -117,8 +117,7 @@ tests/cases/conformance/types/tuple/variadicTuples2.ts(130,25): error TS2345: Ar ~~~ !!! error TS2322: Type '[string, string, number, number]' is not assignable to type '[...string[], number]'. !!! error TS2322: Type at positions 0 through 2 in source is not compatible with type at position 0 in target. -!!! error TS2322: Type 'string | number' is not assignable to type 'string'. -!!! error TS2322: Type 'number' is not assignable to type 'string'. +!!! error TS2322: Type 'number' is not assignable to type 'string'. declare function ft1(...args: [...strs: string[], num: number]): void; ft1(5); @@ -128,8 +127,7 @@ tests/cases/conformance/types/tuple/variadicTuples2.ts(130,25): error TS2345: Ar ~~~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '["abc", "def", 5, 6]' is not assignable to parameter of type '[...strs: string[], num: number]'. !!! error TS2345: Type at positions 0 through 2 in source is not compatible with type at position 0 in target. -!!! error TS2345: Type 'string | number' is not assignable to type 'string'. -!!! error TS2345: Type 'number' is not assignable to type 'string'. +!!! error TS2345: Type 'number' is not assignable to type 'string'. declare let tt2: [number, ...string[], number]; tt2 = [0]; // Error @@ -148,8 +146,7 @@ tests/cases/conformance/types/tuple/variadicTuples2.ts(130,25): error TS2345: Ar ~~~ !!! error TS2322: Type '[number, string, number, string]' is not assignable to type '[number, ...string[], number]'. !!! error TS2322: Type at positions 1 through 2 in source is not compatible with type at position 1 in target. -!!! error TS2322: Type 'string | number' is not assignable to type 'string'. -!!! error TS2322: Type 'number' is not assignable to type 'string'. +!!! error TS2322: Type 'number' is not assignable to type 'string'. tt2 = [true, 'abc', 'def', 1]; // Error ~~~~ !!! error TS2322: Type 'boolean' is not assignable to type 'number'. @@ -176,8 +173,7 @@ tests/cases/conformance/types/tuple/variadicTuples2.ts(130,25): error TS2345: Ar ~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '["abc", 1, "def"]' is not assignable to parameter of type '[...strs: string[], n2: number]'. !!! error TS2345: Type at positions 0 through 1 in source is not compatible with type at position 0 in target. -!!! error TS2345: Type 'string | number' is not assignable to type 'string'. -!!! error TS2345: Type 'number' is not assignable to type 'string'. +!!! error TS2345: Type 'number' is not assignable to type 'string'. ft2(true, 'abc', 'def', 1); // Error ~~~~ !!! error TS2345: Argument of type 'boolean' is not assignable to parameter of type 'number'. @@ -204,9 +200,19 @@ tests/cases/conformance/types/tuple/variadicTuples2.ts(130,25): error TS2345: Ar ~ !!! error TS2322: Type '[number, ...T]' is not assignable to type '[number, ...number[]]'. !!! error TS2322: Type at position 1 in source is not compatible with type at position 1 in target. -!!! error TS2322: Type 'T[number]' is not assignable to type 'number'. +!!! error TS2322: Type 'T' is not assignable to type 'number[]'. +!!! error TS2322: Type 'unknown[]' is not assignable to type 'number[]'. +!!! error TS2322: Type 'unknown' is not assignable to type 'number'. } + // repro #50216 + declare let tt3: [number, string, ...any[]] + let tt4: [number, ...number[]] = tt3 // Error + ~~~ +!!! error TS2322: Type '[number, string, ...any[]]' is not assignable to type '[number, ...number[]]'. +!!! error TS2322: Type at positions 1 through 2 in source is not compatible with type at position 1 in target. +!!! error TS2322: Type 'string' is not assignable to type 'number'. + // Inference function pipe(...args: [...T, (...values: T) => void]) { @@ -274,7 +280,7 @@ tests/cases/conformance/types/tuple/variadicTuples2.ts(130,25): error TS2345: Ar // Repro from #39595 declare function foo(...stringsAndNumber: readonly [...S, number]): [...S, number]; - + const a1 = foo('blah1', 1); const b1 = foo('blah1', 'blah2', 1); const c1 = foo(1); // Error @@ -287,6 +293,5 @@ tests/cases/conformance/types/tuple/variadicTuples2.ts(130,25): error TS2345: Ar ~~~~~~~~~~~~~~~~ !!! error TS2345: Argument of type '["blah2", 1, 2, 3]' is not assignable to parameter of type '[...string[], number]'. !!! error TS2345: Type at positions 0 through 2 in source is not compatible with type at position 0 in target. -!!! error TS2345: Type 'string | number' is not assignable to type 'string'. -!!! error TS2345: Type 'number' is not assignable to type 'string'. +!!! error TS2345: Type 'number' is not assignable to type 'string'. \ No newline at end of file diff --git a/tests/baselines/reference/variadicTuples2.js b/tests/baselines/reference/variadicTuples2.js index e84d0bb3d85df..12fac38e26951 100644 --- a/tests/baselines/reference/variadicTuples2.js +++ b/tests/baselines/reference/variadicTuples2.js @@ -75,6 +75,10 @@ function ft3(x: [number, ...T], y: [number, number], z: [nu z = x; // Error } +// repro #50216 +declare let tt3: [number, string, ...any[]] +let tt4: [number, ...number[]] = tt3 // Error + // Inference function pipe(...args: [...T, (...values: T) => void]) { @@ -123,7 +127,7 @@ fn2([1, 'abc', true]); // [number, boolean] // Repro from #39595 declare function foo(...stringsAndNumber: readonly [...S, number]): [...S, number]; - + const a1 = foo('blah1', 1); const b1 = foo('blah1', 'blah2', 1); const c1 = foo(1); // Error @@ -173,6 +177,7 @@ function ft3(x, y, z) { y = x; // Error z = x; // Error } +var tt4 = tt3; // Error // Inference function pipe() { var args = []; @@ -258,6 +263,8 @@ declare function ft1(...args: [...strs: string[], num: number]): void; declare let tt2: [number, ...string[], number]; declare function ft2(n1: number, ...rest: [...strs: string[], n2: number]): void; declare function ft3(x: [number, ...T], y: [number, number], z: [number, ...number[]]): void; +declare let tt3: [number, string, ...any[]]; +declare let tt4: [number, ...number[]]; declare function pipe(...args: [...T, (...values: T) => void]): void; declare const sa: string[]; declare function fn1(t: [...unknown[], T, U]): [T, U]; diff --git a/tests/baselines/reference/variadicTuples2.symbols b/tests/baselines/reference/variadicTuples2.symbols index 82f2ccb86a89a..776b2d94d54d3 100644 --- a/tests/baselines/reference/variadicTuples2.symbols +++ b/tests/baselines/reference/variadicTuples2.symbols @@ -230,175 +230,183 @@ function ft3(x: [number, ...T], y: [number, number], z: [nu >x : Symbol(x, Decl(variadicTuples2.ts, 69, 34)) } +// repro #50216 +declare let tt3: [number, string, ...any[]] +>tt3 : Symbol(tt3, Decl(variadicTuples2.ts, 77, 11)) + +let tt4: [number, ...number[]] = tt3 // Error +>tt4 : Symbol(tt4, Decl(variadicTuples2.ts, 78, 3)) +>tt3 : Symbol(tt3, Decl(variadicTuples2.ts, 77, 11)) + // Inference function pipe(...args: [...T, (...values: T) => void]) { ->pipe : Symbol(pipe, Decl(variadicTuples2.ts, 74, 1)) ->T : Symbol(T, Decl(variadicTuples2.ts, 78, 14)) ->args : Symbol(args, Decl(variadicTuples2.ts, 78, 44)) ->T : Symbol(T, Decl(variadicTuples2.ts, 78, 14)) ->values : Symbol(values, Decl(variadicTuples2.ts, 78, 61)) ->T : Symbol(T, Decl(variadicTuples2.ts, 78, 14)) +>pipe : Symbol(pipe, Decl(variadicTuples2.ts, 78, 36)) +>T : Symbol(T, Decl(variadicTuples2.ts, 82, 14)) +>args : Symbol(args, Decl(variadicTuples2.ts, 82, 44)) +>T : Symbol(T, Decl(variadicTuples2.ts, 82, 14)) +>values : Symbol(values, Decl(variadicTuples2.ts, 82, 61)) +>T : Symbol(T, Decl(variadicTuples2.ts, 82, 14)) const callback = args[args.length - 1] as (...values: T) => void; ->callback : Symbol(callback, Decl(variadicTuples2.ts, 79, 9)) ->args : Symbol(args, Decl(variadicTuples2.ts, 78, 44)) +>callback : Symbol(callback, Decl(variadicTuples2.ts, 83, 9)) +>args : Symbol(args, Decl(variadicTuples2.ts, 82, 44)) >args.length : Symbol(length) ->args : Symbol(args, Decl(variadicTuples2.ts, 78, 44)) +>args : Symbol(args, Decl(variadicTuples2.ts, 82, 44)) >length : Symbol(length) ->values : Symbol(values, Decl(variadicTuples2.ts, 79, 47)) ->T : Symbol(T, Decl(variadicTuples2.ts, 78, 14)) +>values : Symbol(values, Decl(variadicTuples2.ts, 83, 47)) +>T : Symbol(T, Decl(variadicTuples2.ts, 82, 14)) const values = args.slice(0, -1) as unknown as T; ->values : Symbol(values, Decl(variadicTuples2.ts, 80, 9)) +>values : Symbol(values, Decl(variadicTuples2.ts, 84, 9)) >args.slice : Symbol(Array.slice, Decl(lib.es5.d.ts, --, --)) ->args : Symbol(args, Decl(variadicTuples2.ts, 78, 44)) +>args : Symbol(args, Decl(variadicTuples2.ts, 82, 44)) >slice : Symbol(Array.slice, Decl(lib.es5.d.ts, --, --)) ->T : Symbol(T, Decl(variadicTuples2.ts, 78, 14)) +>T : Symbol(T, Decl(variadicTuples2.ts, 82, 14)) callback(...values); ->callback : Symbol(callback, Decl(variadicTuples2.ts, 79, 9)) ->values : Symbol(values, Decl(variadicTuples2.ts, 80, 9)) +>callback : Symbol(callback, Decl(variadicTuples2.ts, 83, 9)) +>values : Symbol(values, Decl(variadicTuples2.ts, 84, 9)) } pipe("foo", 123, true, (a, b, c) => { ->pipe : Symbol(pipe, Decl(variadicTuples2.ts, 74, 1)) ->a : Symbol(a, Decl(variadicTuples2.ts, 84, 24)) ->b : Symbol(b, Decl(variadicTuples2.ts, 84, 26)) ->c : Symbol(c, Decl(variadicTuples2.ts, 84, 29)) +>pipe : Symbol(pipe, Decl(variadicTuples2.ts, 78, 36)) +>a : Symbol(a, Decl(variadicTuples2.ts, 88, 24)) +>b : Symbol(b, Decl(variadicTuples2.ts, 88, 26)) +>c : Symbol(c, Decl(variadicTuples2.ts, 88, 29)) a; // string ->a : Symbol(a, Decl(variadicTuples2.ts, 84, 24)) +>a : Symbol(a, Decl(variadicTuples2.ts, 88, 24)) b; // number ->b : Symbol(b, Decl(variadicTuples2.ts, 84, 26)) +>b : Symbol(b, Decl(variadicTuples2.ts, 88, 26)) c; // boolean ->c : Symbol(c, Decl(variadicTuples2.ts, 84, 29)) +>c : Symbol(c, Decl(variadicTuples2.ts, 88, 29)) }) pipe("foo", 123, true, (...x) => { ->pipe : Symbol(pipe, Decl(variadicTuples2.ts, 74, 1)) ->x : Symbol(x, Decl(variadicTuples2.ts, 90, 24)) +>pipe : Symbol(pipe, Decl(variadicTuples2.ts, 78, 36)) +>x : Symbol(x, Decl(variadicTuples2.ts, 94, 24)) x; // [string, number, boolean] ->x : Symbol(x, Decl(variadicTuples2.ts, 90, 24)) +>x : Symbol(x, Decl(variadicTuples2.ts, 94, 24)) }); declare const sa: string[]; ->sa : Symbol(sa, Decl(variadicTuples2.ts, 94, 13)) +>sa : Symbol(sa, Decl(variadicTuples2.ts, 98, 13)) pipe(...sa, (...x) => { ->pipe : Symbol(pipe, Decl(variadicTuples2.ts, 74, 1)) ->sa : Symbol(sa, Decl(variadicTuples2.ts, 94, 13)) ->x : Symbol(x, Decl(variadicTuples2.ts, 96, 13)) +>pipe : Symbol(pipe, Decl(variadicTuples2.ts, 78, 36)) +>sa : Symbol(sa, Decl(variadicTuples2.ts, 98, 13)) +>x : Symbol(x, Decl(variadicTuples2.ts, 100, 13)) x; // string[] ->x : Symbol(x, Decl(variadicTuples2.ts, 96, 13)) +>x : Symbol(x, Decl(variadicTuples2.ts, 100, 13)) }); pipe(1, ...sa, 2, (...x) => { ->pipe : Symbol(pipe, Decl(variadicTuples2.ts, 74, 1)) ->sa : Symbol(sa, Decl(variadicTuples2.ts, 94, 13)) ->x : Symbol(x, Decl(variadicTuples2.ts, 100, 19)) +>pipe : Symbol(pipe, Decl(variadicTuples2.ts, 78, 36)) +>sa : Symbol(sa, Decl(variadicTuples2.ts, 98, 13)) +>x : Symbol(x, Decl(variadicTuples2.ts, 104, 19)) x; // [number, ...string[], number] ->x : Symbol(x, Decl(variadicTuples2.ts, 100, 19)) +>x : Symbol(x, Decl(variadicTuples2.ts, 104, 19)) let qq = x[x.length - 1]; ->qq : Symbol(qq, Decl(variadicTuples2.ts, 102, 7)) ->x : Symbol(x, Decl(variadicTuples2.ts, 100, 19)) +>qq : Symbol(qq, Decl(variadicTuples2.ts, 106, 7)) +>x : Symbol(x, Decl(variadicTuples2.ts, 104, 19)) >x.length : Symbol(length) ->x : Symbol(x, Decl(variadicTuples2.ts, 100, 19)) +>x : Symbol(x, Decl(variadicTuples2.ts, 104, 19)) >length : Symbol(length) let ww = x[0] ->ww : Symbol(ww, Decl(variadicTuples2.ts, 103, 7)) ->x : Symbol(x, Decl(variadicTuples2.ts, 100, 19)) +>ww : Symbol(ww, Decl(variadicTuples2.ts, 107, 7)) +>x : Symbol(x, Decl(variadicTuples2.ts, 104, 19)) >0 : Symbol(0) }); pipe(1, 2, 3, 4); // Error ->pipe : Symbol(pipe, Decl(variadicTuples2.ts, 74, 1)) +>pipe : Symbol(pipe, Decl(variadicTuples2.ts, 78, 36)) pipe(...sa); // Error ->pipe : Symbol(pipe, Decl(variadicTuples2.ts, 74, 1)) ->sa : Symbol(sa, Decl(variadicTuples2.ts, 94, 13)) +>pipe : Symbol(pipe, Decl(variadicTuples2.ts, 78, 36)) +>sa : Symbol(sa, Decl(variadicTuples2.ts, 98, 13)) declare function fn1(t: [...unknown[], T, U]): [T, U]; ->fn1 : Symbol(fn1, Decl(variadicTuples2.ts, 107, 12)) ->T : Symbol(T, Decl(variadicTuples2.ts, 109, 21)) ->U : Symbol(U, Decl(variadicTuples2.ts, 109, 23)) ->t : Symbol(t, Decl(variadicTuples2.ts, 109, 27)) ->T : Symbol(T, Decl(variadicTuples2.ts, 109, 21)) ->U : Symbol(U, Decl(variadicTuples2.ts, 109, 23)) ->T : Symbol(T, Decl(variadicTuples2.ts, 109, 21)) ->U : Symbol(U, Decl(variadicTuples2.ts, 109, 23)) +>fn1 : Symbol(fn1, Decl(variadicTuples2.ts, 111, 12)) +>T : Symbol(T, Decl(variadicTuples2.ts, 113, 21)) +>U : Symbol(U, Decl(variadicTuples2.ts, 113, 23)) +>t : Symbol(t, Decl(variadicTuples2.ts, 113, 27)) +>T : Symbol(T, Decl(variadicTuples2.ts, 113, 21)) +>U : Symbol(U, Decl(variadicTuples2.ts, 113, 23)) +>T : Symbol(T, Decl(variadicTuples2.ts, 113, 21)) +>U : Symbol(U, Decl(variadicTuples2.ts, 113, 23)) fn1([]); // Error ->fn1 : Symbol(fn1, Decl(variadicTuples2.ts, 107, 12)) +>fn1 : Symbol(fn1, Decl(variadicTuples2.ts, 111, 12)) fn1([1]); // Error ->fn1 : Symbol(fn1, Decl(variadicTuples2.ts, 107, 12)) +>fn1 : Symbol(fn1, Decl(variadicTuples2.ts, 111, 12)) fn1([1, 'abc']); // [number, string] ->fn1 : Symbol(fn1, Decl(variadicTuples2.ts, 107, 12)) +>fn1 : Symbol(fn1, Decl(variadicTuples2.ts, 111, 12)) fn1([1, 'abc', true]); // [string, boolean] ->fn1 : Symbol(fn1, Decl(variadicTuples2.ts, 107, 12)) +>fn1 : Symbol(fn1, Decl(variadicTuples2.ts, 111, 12)) declare function fn2(t: [T, ...unknown[], U]): [T, U]; ->fn2 : Symbol(fn2, Decl(variadicTuples2.ts, 113, 22)) ->T : Symbol(T, Decl(variadicTuples2.ts, 115, 21)) ->U : Symbol(U, Decl(variadicTuples2.ts, 115, 23)) ->t : Symbol(t, Decl(variadicTuples2.ts, 115, 27)) ->T : Symbol(T, Decl(variadicTuples2.ts, 115, 21)) ->U : Symbol(U, Decl(variadicTuples2.ts, 115, 23)) ->T : Symbol(T, Decl(variadicTuples2.ts, 115, 21)) ->U : Symbol(U, Decl(variadicTuples2.ts, 115, 23)) +>fn2 : Symbol(fn2, Decl(variadicTuples2.ts, 117, 22)) +>T : Symbol(T, Decl(variadicTuples2.ts, 119, 21)) +>U : Symbol(U, Decl(variadicTuples2.ts, 119, 23)) +>t : Symbol(t, Decl(variadicTuples2.ts, 119, 27)) +>T : Symbol(T, Decl(variadicTuples2.ts, 119, 21)) +>U : Symbol(U, Decl(variadicTuples2.ts, 119, 23)) +>T : Symbol(T, Decl(variadicTuples2.ts, 119, 21)) +>U : Symbol(U, Decl(variadicTuples2.ts, 119, 23)) fn2([]); // Error ->fn2 : Symbol(fn2, Decl(variadicTuples2.ts, 113, 22)) +>fn2 : Symbol(fn2, Decl(variadicTuples2.ts, 117, 22)) fn2([1]); // Error ->fn2 : Symbol(fn2, Decl(variadicTuples2.ts, 113, 22)) +>fn2 : Symbol(fn2, Decl(variadicTuples2.ts, 117, 22)) fn2([1, 'abc']); // [number, string] ->fn2 : Symbol(fn2, Decl(variadicTuples2.ts, 113, 22)) +>fn2 : Symbol(fn2, Decl(variadicTuples2.ts, 117, 22)) fn2([1, 'abc', true]); // [number, boolean] ->fn2 : Symbol(fn2, Decl(variadicTuples2.ts, 113, 22)) +>fn2 : Symbol(fn2, Decl(variadicTuples2.ts, 117, 22)) // Repro from #39595 declare function foo(...stringsAndNumber: readonly [...S, number]): [...S, number]; ->foo : Symbol(foo, Decl(variadicTuples2.ts, 119, 22)) ->S : Symbol(S, Decl(variadicTuples2.ts, 123, 21)) ->stringsAndNumber : Symbol(stringsAndNumber, Decl(variadicTuples2.ts, 123, 63)) ->S : Symbol(S, Decl(variadicTuples2.ts, 123, 21)) ->S : Symbol(S, Decl(variadicTuples2.ts, 123, 21)) - +>foo : Symbol(foo, Decl(variadicTuples2.ts, 123, 22)) +>S : Symbol(S, Decl(variadicTuples2.ts, 127, 21)) +>stringsAndNumber : Symbol(stringsAndNumber, Decl(variadicTuples2.ts, 127, 63)) +>S : Symbol(S, Decl(variadicTuples2.ts, 127, 21)) +>S : Symbol(S, Decl(variadicTuples2.ts, 127, 21)) + const a1 = foo('blah1', 1); ->a1 : Symbol(a1, Decl(variadicTuples2.ts, 125, 5)) ->foo : Symbol(foo, Decl(variadicTuples2.ts, 119, 22)) +>a1 : Symbol(a1, Decl(variadicTuples2.ts, 129, 5)) +>foo : Symbol(foo, Decl(variadicTuples2.ts, 123, 22)) const b1 = foo('blah1', 'blah2', 1); ->b1 : Symbol(b1, Decl(variadicTuples2.ts, 126, 5)) ->foo : Symbol(foo, Decl(variadicTuples2.ts, 119, 22)) +>b1 : Symbol(b1, Decl(variadicTuples2.ts, 130, 5)) +>foo : Symbol(foo, Decl(variadicTuples2.ts, 123, 22)) const c1 = foo(1); // Error ->c1 : Symbol(c1, Decl(variadicTuples2.ts, 127, 5)) ->foo : Symbol(foo, Decl(variadicTuples2.ts, 119, 22)) +>c1 : Symbol(c1, Decl(variadicTuples2.ts, 131, 5)) +>foo : Symbol(foo, Decl(variadicTuples2.ts, 123, 22)) const d1 = foo(1, 2); // Error ->d1 : Symbol(d1, Decl(variadicTuples2.ts, 128, 5)) ->foo : Symbol(foo, Decl(variadicTuples2.ts, 119, 22)) +>d1 : Symbol(d1, Decl(variadicTuples2.ts, 132, 5)) +>foo : Symbol(foo, Decl(variadicTuples2.ts, 123, 22)) const e1 = foo('blah1', 'blah2', 1, 2, 3); // Error ->e1 : Symbol(e1, Decl(variadicTuples2.ts, 129, 5)) ->foo : Symbol(foo, Decl(variadicTuples2.ts, 119, 22)) +>e1 : Symbol(e1, Decl(variadicTuples2.ts, 133, 5)) +>foo : Symbol(foo, Decl(variadicTuples2.ts, 123, 22)) diff --git a/tests/baselines/reference/variadicTuples2.types b/tests/baselines/reference/variadicTuples2.types index f4c199cfc9c06..d21c09a69eb8f 100644 --- a/tests/baselines/reference/variadicTuples2.types +++ b/tests/baselines/reference/variadicTuples2.types @@ -297,6 +297,14 @@ function ft3(x: [number, ...T], y: [number, number], z: [nu >x : [number, ...T] } +// repro #50216 +declare let tt3: [number, string, ...any[]] +>tt3 : [number, string, ...any[]] + +let tt4: [number, ...number[]] = tt3 // Error +>tt4 : [number, ...number[]] +>tt3 : [number, string, ...any[]] + // Inference function pipe(...args: [...T, (...values: T) => void]) { @@ -497,7 +505,7 @@ fn2([1, 'abc', true]); // [number, boolean] declare function foo(...stringsAndNumber: readonly [...S, number]): [...S, number]; >foo : (...stringsAndNumber: readonly [...S, number]) => [...S, number] >stringsAndNumber : readonly [...S, number] - + const a1 = foo('blah1', 1); >a1 : ["blah1", number] >foo('blah1', 1) : ["blah1", number] diff --git a/tests/cases/conformance/types/tuple/variadicTuples2.ts b/tests/cases/conformance/types/tuple/variadicTuples2.ts index aa34bd4630c0c..8ad04d44904b1 100644 --- a/tests/cases/conformance/types/tuple/variadicTuples2.ts +++ b/tests/cases/conformance/types/tuple/variadicTuples2.ts @@ -77,6 +77,10 @@ function ft3(x: [number, ...T], y: [number, number], z: [nu z = x; // Error } +// repro #50216 +declare let tt3: [number, string, ...any[]] +let tt4: [number, ...number[]] = tt3 // Error + // Inference function pipe(...args: [...T, (...values: T) => void]) { @@ -125,7 +129,7 @@ fn2([1, 'abc', true]); // [number, boolean] // Repro from #39595 declare function foo(...stringsAndNumber: readonly [...S, number]): [...S, number]; - + const a1 = foo('blah1', 1); const b1 = foo('blah1', 'blah2', 1); const c1 = foo(1); // Error