Fixed reported errors for variadic element mismatches (#58708)

This commit is contained in:
Mateusz Burzyński
2024-06-14 22:17:42 +02:00
committed by GitHub
parent e6add984c7
commit 61ffce078b
7 changed files with 162 additions and 12 deletions

View File

@@ -23665,7 +23665,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const sourceArity = getTypeReferenceArity(source);
const targetArity = getTypeReferenceArity(target);
const sourceRestFlag = isTupleType(source) ? source.target.combinedFlags & ElementFlags.Rest : ElementFlags.Rest;
const targetRestFlag = target.target.combinedFlags & ElementFlags.Rest;
const targetHasRestElement = !!(target.target.combinedFlags & ElementFlags.Variable);
const sourceMinLength = isTupleType(source) ? source.target.minLength : 0;
const targetMinLength = target.target.minLength;
if (!sourceRestFlag && sourceArity < targetMinLength) {
@@ -23674,13 +23674,13 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
return Ternary.False;
}
if (!targetRestFlag && targetArity < sourceMinLength) {
if (!targetHasRestElement && targetArity < sourceMinLength) {
if (reportErrors) {
reportError(Diagnostics.Source_has_0_element_s_but_target_allows_only_1, sourceMinLength, targetArity);
}
return Ternary.False;
}
if (!targetRestFlag && (sourceRestFlag || targetArity < sourceArity)) {
if (!targetHasRestElement && (sourceRestFlag || targetArity < sourceArity)) {
if (reportErrors) {
if (sourceMinLength < targetMinLength) {
reportError(Diagnostics.Target_requires_0_element_s_but_source_may_have_fewer, targetMinLength);
@@ -23695,7 +23695,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const targetTypeArguments = getTypeArguments(target);
const targetStartCount = getStartElementCount(target.target, ElementFlags.NonRest);
const targetEndCount = getEndElementCount(target.target, ElementFlags.NonRest);
const targetHasRestElement = target.target.hasRestElement;
let canExcludeDiscriminants = !!excludedProperties;
for (let sourcePosition = 0; sourcePosition < sourceArity; sourcePosition++) {
const sourceFlags = isTupleType(source) ? source.target.elementFlags[sourcePosition] : ElementFlags.Rest;

View File

@@ -5,9 +5,9 @@ variadicTuples1.ts(62,5): error TS2345: Argument of type '[]' is not assignable
variadicTuples1.ts(131,9): error TS2344: Type 'V' does not satisfy the constraint 'unknown[]'.
The type 'readonly unknown[]' is 'readonly' and cannot be assigned to the mutable type 'unknown[]'.
variadicTuples1.ts(149,5): error TS2322: Type '[string, ...unknown[]]' is not assignable to type '[string, ...T]'.
Target requires 2 element(s) but source may have fewer.
Source provides no match for variadic element at position 1 in target.
variadicTuples1.ts(151,5): error TS2322: Type '[string, ...unknown[]]' is not assignable to type '[string, ...U]'.
Target requires 2 element(s) but source may have fewer.
Source provides no match for variadic element at position 1 in target.
variadicTuples1.ts(152,5): error TS2322: Type '[string, ...T]' is not assignable to type '[string, ...U]'.
Type at position 1 in source is not compatible with type at position 1 in target.
Type 'T' is not assignable to type 'U'.
@@ -22,7 +22,7 @@ variadicTuples1.ts(170,5): error TS2322: Type 'T' is not assignable to type '[..
variadicTuples1.ts(171,5): error TS4104: The type 'readonly [...T]' is 'readonly' and cannot be assigned to the mutable type '[...T]'.
variadicTuples1.ts(181,5): error TS2322: Type 'T' is not assignable to type '[...U]'.
Type 'string[]' is not assignable to type '[...U]'.
Target requires 1 element(s) but source may have fewer.
Source provides no match for variadic element at position 0 in target.
variadicTuples1.ts(182,5): error TS2322: Type '[...T]' is not assignable to type '[...U]'.
Type 'T' is not assignable to type 'U'.
'T' is assignable to the constraint of type 'U', but 'U' could be instantiated with a different subtype of constraint 'string[]'.
@@ -211,12 +211,12 @@ variadicTuples1.ts(411,7): error TS2322: Type '[boolean, false]' is not assignab
y = x; // Error
~
!!! error TS2322: Type '[string, ...unknown[]]' is not assignable to type '[string, ...T]'.
!!! error TS2322: Target requires 2 element(s) but source may have fewer.
!!! error TS2322: Source provides no match for variadic element at position 1 in target.
y = z;
z = x; // Error
~
!!! error TS2322: Type '[string, ...unknown[]]' is not assignable to type '[string, ...U]'.
!!! error TS2322: Target requires 2 element(s) but source may have fewer.
!!! error TS2322: Source provides no match for variadic element at position 1 in target.
z = y; // Error
~
!!! error TS2322: Type '[string, ...T]' is not assignable to type '[string, ...U]'.
@@ -268,7 +268,7 @@ variadicTuples1.ts(411,7): error TS2322: Type '[boolean, false]' is not assignab
~~
!!! error TS2322: Type 'T' is not assignable to type '[...U]'.
!!! error TS2322: Type 'string[]' is not assignable to type '[...U]'.
!!! error TS2322: Target requires 1 element(s) but source may have fewer.
!!! error TS2322: Source provides no match for variadic element at position 0 in target.
t2 = t1; // Error
~~
!!! error TS2322: Type '[...T]' is not assignable to type '[...U]'.

View File

@@ -38,7 +38,7 @@ variadicTuples2.ts(73,8): error TS2345: Argument of type '["abc", "def", true]'
variadicTuples2.ts(76,5): error TS2322: Type '[number, number]' is not assignable to type '[number, ...T]'.
Source provides no match for variadic element at position 1 in target.
variadicTuples2.ts(77,5): error TS2322: Type '[number, ...number[]]' is not assignable to type '[number, ...T]'.
Target requires 2 element(s) but source may have fewer.
Source provides no match for variadic element at position 1 in target.
variadicTuples2.ts(78,5): error TS2322: Type '[number, ...T]' is not assignable to type '[number, number]'.
Type '[number, ...unknown[]]' is not assignable to type '[number, number]'.
Target requires 2 element(s) but source may have fewer.
@@ -208,7 +208,7 @@ variadicTuples2.ts(139,25): error TS2345: Argument of type '["blah2", 1, 2, 3]'
x = z; // Error
~
!!! error TS2322: Type '[number, ...number[]]' is not assignable to type '[number, ...T]'.
!!! error TS2322: Target requires 2 element(s) but source may have fewer.
!!! error TS2322: Source provides no match for variadic element at position 1 in target.
y = x; // Error
~
!!! error TS2322: Type '[number, ...T]' is not assignable to type '[number, number]'.

View File

@@ -0,0 +1,35 @@
variadicTuples3.ts(5,3): error TS2322: Type 'any[]' is not assignable to type '[...T, ...P]'.
Source provides no match for variadic element at position 0 in target.
variadicTuples3.ts(10,3): error TS2322: Type '[any, any]' is not assignable to type '[...T, ...P]'.
Source provides no match for variadic element at position 0 in target.
variadicTuples3.ts(15,3): error TS2322: Type '[any, any, any]' is not assignable to type '[...T, ...P]'.
Source provides no match for variadic element at position 0 in target.
==== variadicTuples3.ts (3 errors) ====
// https://github.com/microsoft/TypeScript/issues/58697
function test1<T extends any[], P extends any[]>(): [...T, ...P] {
let x: any[] = [];
return x;
~~~~~~
!!! error TS2322: Type 'any[]' is not assignable to type '[...T, ...P]'.
!!! error TS2322: Source provides no match for variadic element at position 0 in target.
}
function test2<T extends any[], P extends any[]>(): [...T, ...P] {
let x: [any, any] = [null, null];
return x;
~~~~~~
!!! error TS2322: Type '[any, any]' is not assignable to type '[...T, ...P]'.
!!! error TS2322: Source provides no match for variadic element at position 0 in target.
}
function test3<T extends any[], P extends any[]>(): [...T, ...P] {
let x: [any, any, any] = [null, null, null];
return x;
~~~~~~
!!! error TS2322: Type '[any, any, any]' is not assignable to type '[...T, ...P]'.
!!! error TS2322: Source provides no match for variadic element at position 0 in target.
}

View File

@@ -0,0 +1,47 @@
//// [tests/cases/conformance/types/tuple/variadicTuples3.ts] ////
=== variadicTuples3.ts ===
// https://github.com/microsoft/TypeScript/issues/58697
function test1<T extends any[], P extends any[]>(): [...T, ...P] {
>test1 : Symbol(test1, Decl(variadicTuples3.ts, 0, 0))
>T : Symbol(T, Decl(variadicTuples3.ts, 2, 15))
>P : Symbol(P, Decl(variadicTuples3.ts, 2, 31))
>T : Symbol(T, Decl(variadicTuples3.ts, 2, 15))
>P : Symbol(P, Decl(variadicTuples3.ts, 2, 31))
let x: any[] = [];
>x : Symbol(x, Decl(variadicTuples3.ts, 3, 5))
return x;
>x : Symbol(x, Decl(variadicTuples3.ts, 3, 5))
}
function test2<T extends any[], P extends any[]>(): [...T, ...P] {
>test2 : Symbol(test2, Decl(variadicTuples3.ts, 5, 1))
>T : Symbol(T, Decl(variadicTuples3.ts, 7, 15))
>P : Symbol(P, Decl(variadicTuples3.ts, 7, 31))
>T : Symbol(T, Decl(variadicTuples3.ts, 7, 15))
>P : Symbol(P, Decl(variadicTuples3.ts, 7, 31))
let x: [any, any] = [null, null];
>x : Symbol(x, Decl(variadicTuples3.ts, 8, 5))
return x;
>x : Symbol(x, Decl(variadicTuples3.ts, 8, 5))
}
function test3<T extends any[], P extends any[]>(): [...T, ...P] {
>test3 : Symbol(test3, Decl(variadicTuples3.ts, 10, 1))
>T : Symbol(T, Decl(variadicTuples3.ts, 12, 15))
>P : Symbol(P, Decl(variadicTuples3.ts, 12, 31))
>T : Symbol(T, Decl(variadicTuples3.ts, 12, 15))
>P : Symbol(P, Decl(variadicTuples3.ts, 12, 31))
let x: [any, any, any] = [null, null, null];
>x : Symbol(x, Decl(variadicTuples3.ts, 13, 5))
return x;
>x : Symbol(x, Decl(variadicTuples3.ts, 13, 5))
}

View File

@@ -0,0 +1,50 @@
//// [tests/cases/conformance/types/tuple/variadicTuples3.ts] ////
=== variadicTuples3.ts ===
// https://github.com/microsoft/TypeScript/issues/58697
function test1<T extends any[], P extends any[]>(): [...T, ...P] {
>test1 : <T extends any[], P extends any[]>() => [...T, ...P]
> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^ ^^^^^^^
let x: any[] = [];
>x : any[]
> : ^^^^^
>[] : never[]
> : ^^^^^^^
return x;
>x : any[]
> : ^^^^^
}
function test2<T extends any[], P extends any[]>(): [...T, ...P] {
>test2 : <T extends any[], P extends any[]>() => [...T, ...P]
> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^ ^^^^^^^
let x: [any, any] = [null, null];
>x : [any, any]
> : ^^^^^^^^^^
>[null, null] : [null, null]
> : ^^^^^^^^^^^^
return x;
>x : [any, any]
> : ^^^^^^^^^^
}
function test3<T extends any[], P extends any[]>(): [...T, ...P] {
>test3 : <T extends any[], P extends any[]>() => [...T, ...P]
> : ^ ^^^^^^^^^ ^^ ^^^^^^^^^ ^^^^^^^
let x: [any, any, any] = [null, null, null];
>x : [any, any, any]
> : ^^^^^^^^^^^^^^^
>[null, null, null] : [null, null, null]
> : ^^^^^^^^^^^^^^^^^^
return x;
>x : [any, any, any]
> : ^^^^^^^^^^^^^^^
}

View File

@@ -0,0 +1,19 @@
// @strict: true
// @noEmit: true
// https://github.com/microsoft/TypeScript/issues/58697
function test1<T extends any[], P extends any[]>(): [...T, ...P] {
let x: any[] = [];
return x;
}
function test2<T extends any[], P extends any[]>(): [...T, ...P] {
let x: [any, any] = [null, null];
return x;
}
function test3<T extends any[], P extends any[]>(): [...T, ...P] {
let x: [any, any, any] = [null, null, null];
return x;
}