Fixed the issue with some longer variadic tuples with `any` rest being incorrectly assignable to shorter variadic tuples (#50218)
This commit is contained in:
Родитель
fdcb2ffd1b
Коммит
46b015f2bf
|
@ -20592,28 +20592,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;
|
||||
}
|
||||
|
@ -20622,24 +20629,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;
|
||||
|
|
|
@ -5930,9 +5930,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)[];
|
||||
|
|
|
@ -2781,8 +2781,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;
|
||||
|
|
|
@ -2781,8 +2781,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;
|
||||
|
|
|
@ -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[]];
|
||||
|
||||
|
|
|
@ -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<T extends readonly unknown[]>(...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<S extends readonly [string, ...string[]]>(...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'.
|
||||
|
|
@ -75,6 +75,10 @@ function ft3<T extends unknown[]>(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<T extends readonly unknown[]>(...args: [...T, (...values: T) => void]) {
|
||||
|
@ -123,7 +127,7 @@ fn2([1, 'abc', true]); // [number, boolean]
|
|||
// Repro from #39595
|
||||
|
||||
declare function foo<S extends readonly [string, ...string[]]>(...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<T extends unknown[]>(x: [number, ...T], y: [number, number], z: [number, ...number[]]): void;
|
||||
declare let tt3: [number, string, ...any[]];
|
||||
declare let tt4: [number, ...number[]];
|
||||
declare function pipe<T extends readonly unknown[]>(...args: [...T, (...values: T) => void]): void;
|
||||
declare const sa: string[];
|
||||
declare function fn1<T, U>(t: [...unknown[], T, U]): [T, U];
|
||||
|
|
|
@ -230,175 +230,183 @@ function ft3<T extends unknown[]>(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<T extends readonly unknown[]>(...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<number[]>(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, U>(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, U>(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<S extends readonly [string, ...string[]]>(...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))
|
||||
|
||||
|
|
|
@ -297,6 +297,14 @@ function ft3<T extends unknown[]>(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<T extends readonly unknown[]>(...args: [...T, (...values: T) => void]) {
|
||||
|
@ -497,7 +505,7 @@ fn2([1, 'abc', true]); // [number, boolean]
|
|||
declare function foo<S extends readonly [string, ...string[]]>(...stringsAndNumber: readonly [...S, number]): [...S, number];
|
||||
>foo : <S extends readonly [string, ...string[]]>(...stringsAndNumber: readonly [...S, number]) => [...S, number]
|
||||
>stringsAndNumber : readonly [...S, number]
|
||||
|
||||
|
||||
const a1 = foo('blah1', 1);
|
||||
>a1 : ["blah1", number]
|
||||
>foo('blah1', 1) : ["blah1", number]
|
||||
|
|
|
@ -77,6 +77,10 @@ function ft3<T extends unknown[]>(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<T extends readonly unknown[]>(...args: [...T, (...values: T) => void]) {
|
||||
|
@ -125,7 +129,7 @@ fn2([1, 'abc', true]); // [number, boolean]
|
|||
// Repro from #39595
|
||||
|
||||
declare function foo<S extends readonly [string, ...string[]]>(...stringsAndNumber: readonly [...S, number]): [...S, number];
|
||||
|
||||
|
||||
const a1 = foo('blah1', 1);
|
||||
const b1 = foo('blah1', 'blah2', 1);
|
||||
const c1 = foo(1); // Error
|
||||
|
|
Загрузка…
Ссылка в новой задаче