mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-30 04:16:48 -05:00
Fixed spreading iterables into arguments list directly into rest-only signatures (#52838)
This commit is contained in:
committed by
GitHub
parent
7bee9c55b1
commit
6b71882c4c
@@ -32223,19 +32223,26 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
}
|
||||
|
||||
function getSpreadArgumentType(args: readonly Expression[], index: number, argCount: number, restType: Type, context: InferenceContext | undefined, checkMode: CheckMode) {
|
||||
const inConstContext = isConstTypeVariable(restType);
|
||||
|
||||
if (index >= argCount - 1) {
|
||||
const arg = args[argCount - 1];
|
||||
if (isSpreadArgument(arg)) {
|
||||
// We are inferring from a spread expression in the last argument position, i.e. both the parameter
|
||||
// and the argument are ...x forms.
|
||||
return getMutableArrayOrTupleType(arg.kind === SyntaxKind.SyntheticExpression ? (arg as SyntheticExpression).type :
|
||||
checkExpressionWithContextualType((arg as SpreadElement).expression, restType, context, checkMode));
|
||||
const spreadType = arg.kind === SyntaxKind.SyntheticExpression ? (arg as SyntheticExpression).type :
|
||||
checkExpressionWithContextualType((arg as SpreadElement).expression, restType, context, checkMode);
|
||||
|
||||
if (isArrayLikeType(spreadType)) {
|
||||
return getMutableArrayOrTupleType(spreadType);
|
||||
}
|
||||
|
||||
return createArrayType(checkIteratedTypeOrElementType(IterationUse.Spread, spreadType, undefinedType, arg.kind === SyntaxKind.SpreadElement ? (arg as SpreadElement).expression : arg), inConstContext);
|
||||
}
|
||||
}
|
||||
const types = [];
|
||||
const flags = [];
|
||||
const names = [];
|
||||
const inConstContext = isConstTypeVariable(restType);
|
||||
for (let i = index; i < argCount; i++) {
|
||||
const arg = args[i];
|
||||
if (isSpreadArgument(arg)) {
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
tests/cases/compiler/argumentsSpreadRestIterables.tsx(1,22): error TS2304: Cannot find name 'Iterable'.
|
||||
tests/cases/compiler/argumentsSpreadRestIterables.tsx(8,21): error TS2461: Type '"hello"' is not an array type.
|
||||
tests/cases/compiler/argumentsSpreadRestIterables.tsx(10,27): error TS2461: Type '"hello"' is not an array type.
|
||||
tests/cases/compiler/argumentsSpreadRestIterables.tsx(15,19): error TS2461: Type '"hello"' is not an array type.
|
||||
tests/cases/compiler/argumentsSpreadRestIterables.tsx(17,25): error TS2461: Type '"hello"' is not an array type.
|
||||
|
||||
|
||||
==== tests/cases/compiler/argumentsSpreadRestIterables.tsx (5 errors) ====
|
||||
declare const itNum: Iterable<number>
|
||||
~~~~~~~~
|
||||
!!! error TS2304: Cannot find name 'Iterable'.
|
||||
|
||||
;(function(...rest) {})(...itNum)
|
||||
;(function(a, ...rest) {})('', ...itNum)
|
||||
;(function(a, ...rest) {})('', true, ...itNum)
|
||||
|
||||
declare function fn1<const T extends readonly unknown[]>(...args: T): T;
|
||||
const res1 = fn1(..."hello");
|
||||
~~~~~~~
|
||||
!!! error TS2461: Type '"hello"' is not an array type.
|
||||
const res2 = fn1(...itNum);
|
||||
const res3 = fn1(true, ..."hello");
|
||||
~~~~~~~
|
||||
!!! error TS2461: Type '"hello"' is not an array type.
|
||||
const res4 = fn1(true, ...itNum);
|
||||
|
||||
// repro from #52781
|
||||
declare function foo<T extends unknown[]>(...args: T): T;
|
||||
const p1 = foo(..."hello");
|
||||
~~~~~~~
|
||||
!!! error TS2461: Type '"hello"' is not an array type.
|
||||
const p2 = foo(...itNum);
|
||||
const p3 = foo(true, ..."hello");
|
||||
~~~~~~~
|
||||
!!! error TS2461: Type '"hello"' is not an array type.
|
||||
const p4 = foo(true, ...itNum);
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
=== tests/cases/compiler/argumentsSpreadRestIterables.tsx ===
|
||||
declare const itNum: Iterable<number>
|
||||
>itNum : Symbol(itNum, Decl(argumentsSpreadRestIterables.tsx, 0, 13))
|
||||
>Iterable : Symbol(Iterable)
|
||||
|
||||
;(function(...rest) {})(...itNum)
|
||||
>rest : Symbol(rest, Decl(argumentsSpreadRestIterables.tsx, 2, 11))
|
||||
>itNum : Symbol(itNum, Decl(argumentsSpreadRestIterables.tsx, 0, 13))
|
||||
|
||||
;(function(a, ...rest) {})('', ...itNum)
|
||||
>a : Symbol(a, Decl(argumentsSpreadRestIterables.tsx, 3, 11))
|
||||
>rest : Symbol(rest, Decl(argumentsSpreadRestIterables.tsx, 3, 13))
|
||||
>itNum : Symbol(itNum, Decl(argumentsSpreadRestIterables.tsx, 0, 13))
|
||||
|
||||
;(function(a, ...rest) {})('', true, ...itNum)
|
||||
>a : Symbol(a, Decl(argumentsSpreadRestIterables.tsx, 4, 11))
|
||||
>rest : Symbol(rest, Decl(argumentsSpreadRestIterables.tsx, 4, 13))
|
||||
>itNum : Symbol(itNum, Decl(argumentsSpreadRestIterables.tsx, 0, 13))
|
||||
|
||||
declare function fn1<const T extends readonly unknown[]>(...args: T): T;
|
||||
>fn1 : Symbol(fn1, Decl(argumentsSpreadRestIterables.tsx, 4, 46))
|
||||
>T : Symbol(T, Decl(argumentsSpreadRestIterables.tsx, 6, 21))
|
||||
>args : Symbol(args, Decl(argumentsSpreadRestIterables.tsx, 6, 57))
|
||||
>T : Symbol(T, Decl(argumentsSpreadRestIterables.tsx, 6, 21))
|
||||
>T : Symbol(T, Decl(argumentsSpreadRestIterables.tsx, 6, 21))
|
||||
|
||||
const res1 = fn1(..."hello");
|
||||
>res1 : Symbol(res1, Decl(argumentsSpreadRestIterables.tsx, 7, 5))
|
||||
>fn1 : Symbol(fn1, Decl(argumentsSpreadRestIterables.tsx, 4, 46))
|
||||
|
||||
const res2 = fn1(...itNum);
|
||||
>res2 : Symbol(res2, Decl(argumentsSpreadRestIterables.tsx, 8, 5))
|
||||
>fn1 : Symbol(fn1, Decl(argumentsSpreadRestIterables.tsx, 4, 46))
|
||||
>itNum : Symbol(itNum, Decl(argumentsSpreadRestIterables.tsx, 0, 13))
|
||||
|
||||
const res3 = fn1(true, ..."hello");
|
||||
>res3 : Symbol(res3, Decl(argumentsSpreadRestIterables.tsx, 9, 5))
|
||||
>fn1 : Symbol(fn1, Decl(argumentsSpreadRestIterables.tsx, 4, 46))
|
||||
|
||||
const res4 = fn1(true, ...itNum);
|
||||
>res4 : Symbol(res4, Decl(argumentsSpreadRestIterables.tsx, 10, 5))
|
||||
>fn1 : Symbol(fn1, Decl(argumentsSpreadRestIterables.tsx, 4, 46))
|
||||
>itNum : Symbol(itNum, Decl(argumentsSpreadRestIterables.tsx, 0, 13))
|
||||
|
||||
// repro from #52781
|
||||
declare function foo<T extends unknown[]>(...args: T): T;
|
||||
>foo : Symbol(foo, Decl(argumentsSpreadRestIterables.tsx, 10, 33))
|
||||
>T : Symbol(T, Decl(argumentsSpreadRestIterables.tsx, 13, 21))
|
||||
>args : Symbol(args, Decl(argumentsSpreadRestIterables.tsx, 13, 42))
|
||||
>T : Symbol(T, Decl(argumentsSpreadRestIterables.tsx, 13, 21))
|
||||
>T : Symbol(T, Decl(argumentsSpreadRestIterables.tsx, 13, 21))
|
||||
|
||||
const p1 = foo(..."hello");
|
||||
>p1 : Symbol(p1, Decl(argumentsSpreadRestIterables.tsx, 14, 5))
|
||||
>foo : Symbol(foo, Decl(argumentsSpreadRestIterables.tsx, 10, 33))
|
||||
|
||||
const p2 = foo(...itNum);
|
||||
>p2 : Symbol(p2, Decl(argumentsSpreadRestIterables.tsx, 15, 5))
|
||||
>foo : Symbol(foo, Decl(argumentsSpreadRestIterables.tsx, 10, 33))
|
||||
>itNum : Symbol(itNum, Decl(argumentsSpreadRestIterables.tsx, 0, 13))
|
||||
|
||||
const p3 = foo(true, ..."hello");
|
||||
>p3 : Symbol(p3, Decl(argumentsSpreadRestIterables.tsx, 16, 5))
|
||||
>foo : Symbol(foo, Decl(argumentsSpreadRestIterables.tsx, 10, 33))
|
||||
|
||||
const p4 = foo(true, ...itNum);
|
||||
>p4 : Symbol(p4, Decl(argumentsSpreadRestIterables.tsx, 17, 5))
|
||||
>foo : Symbol(foo, Decl(argumentsSpreadRestIterables.tsx, 10, 33))
|
||||
>itNum : Symbol(itNum, Decl(argumentsSpreadRestIterables.tsx, 0, 13))
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
=== tests/cases/compiler/argumentsSpreadRestIterables.tsx ===
|
||||
declare const itNum: Iterable<number>
|
||||
>itNum : Iterable<number>
|
||||
|
||||
;(function(...rest) {})(...itNum)
|
||||
>(function(...rest) {})(...itNum) : void
|
||||
>(function(...rest) {}) : (...rest: Iterable<number>) => void
|
||||
>function(...rest) {} : (...rest: Iterable<number>) => void
|
||||
>rest : Iterable<number>
|
||||
>...itNum : Iterable<number>
|
||||
>itNum : Iterable<number>
|
||||
|
||||
;(function(a, ...rest) {})('', ...itNum)
|
||||
>(function(a, ...rest) {})('', ...itNum) : void
|
||||
>(function(a, ...rest) {}) : (a: string, ...rest: Iterable<number>) => void
|
||||
>function(a, ...rest) {} : (a: string, ...rest: Iterable<number>) => void
|
||||
>a : string
|
||||
>rest : Iterable<number>
|
||||
>'' : ""
|
||||
>...itNum : Iterable<number>
|
||||
>itNum : Iterable<number>
|
||||
|
||||
;(function(a, ...rest) {})('', true, ...itNum)
|
||||
>(function(a, ...rest) {})('', true, ...itNum) : void
|
||||
>(function(a, ...rest) {}) : (a: string, rest_0: boolean, ...rest_1: any[]) => void
|
||||
>function(a, ...rest) {} : (a: string, rest_0: boolean, ...rest_1: any[]) => void
|
||||
>a : string
|
||||
>rest : [boolean, ...any[]]
|
||||
>'' : ""
|
||||
>true : true
|
||||
>...itNum : Iterable<number>
|
||||
>itNum : Iterable<number>
|
||||
|
||||
declare function fn1<const T extends readonly unknown[]>(...args: T): T;
|
||||
>fn1 : <const T extends readonly unknown[]>(...args: T) => T
|
||||
>args : T
|
||||
|
||||
const res1 = fn1(..."hello");
|
||||
>res1 : readonly any[]
|
||||
>fn1(..."hello") : readonly any[]
|
||||
>fn1 : <const T extends readonly unknown[]>(...args: T) => T
|
||||
>..."hello" : any
|
||||
>"hello" : "hello"
|
||||
|
||||
const res2 = fn1(...itNum);
|
||||
>res2 : Iterable<number>
|
||||
>fn1(...itNum) : Iterable<number>
|
||||
>fn1 : <const T extends readonly unknown[]>(...args: T) => T
|
||||
>...itNum : Iterable<number>
|
||||
>itNum : Iterable<number>
|
||||
|
||||
const res3 = fn1(true, ..."hello");
|
||||
>res3 : readonly [true, ...any[]]
|
||||
>fn1(true, ..."hello") : readonly [true, ...any[]]
|
||||
>fn1 : <const T extends readonly unknown[]>(...args: T) => T
|
||||
>true : true
|
||||
>..."hello" : any
|
||||
>"hello" : "hello"
|
||||
|
||||
const res4 = fn1(true, ...itNum);
|
||||
>res4 : readonly [true, ...any[]]
|
||||
>fn1(true, ...itNum) : readonly [true, ...any[]]
|
||||
>fn1 : <const T extends readonly unknown[]>(...args: T) => T
|
||||
>true : true
|
||||
>...itNum : Iterable<number>
|
||||
>itNum : Iterable<number>
|
||||
|
||||
// repro from #52781
|
||||
declare function foo<T extends unknown[]>(...args: T): T;
|
||||
>foo : <T extends unknown[]>(...args: T) => T
|
||||
>args : T
|
||||
|
||||
const p1 = foo(..."hello");
|
||||
>p1 : any[]
|
||||
>foo(..."hello") : any[]
|
||||
>foo : <T extends unknown[]>(...args: T) => T
|
||||
>..."hello" : any
|
||||
>"hello" : "hello"
|
||||
|
||||
const p2 = foo(...itNum);
|
||||
>p2 : Iterable<number>
|
||||
>foo(...itNum) : Iterable<number>
|
||||
>foo : <T extends unknown[]>(...args: T) => T
|
||||
>...itNum : Iterable<number>
|
||||
>itNum : Iterable<number>
|
||||
|
||||
const p3 = foo(true, ..."hello");
|
||||
>p3 : [boolean, ...any[]]
|
||||
>foo(true, ..."hello") : [boolean, ...any[]]
|
||||
>foo : <T extends unknown[]>(...args: T) => T
|
||||
>true : true
|
||||
>..."hello" : any
|
||||
>"hello" : "hello"
|
||||
|
||||
const p4 = foo(true, ...itNum);
|
||||
>p4 : [boolean, ...any[]]
|
||||
>foo(true, ...itNum) : [boolean, ...any[]]
|
||||
>foo : <T extends unknown[]>(...args: T) => T
|
||||
>true : true
|
||||
>...itNum : Iterable<number>
|
||||
>itNum : Iterable<number>
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
=== tests/cases/compiler/argumentsSpreadRestIterables.tsx ===
|
||||
declare const itNum: Iterable<number>
|
||||
>itNum : Symbol(itNum, Decl(argumentsSpreadRestIterables.tsx, 0, 13))
|
||||
>Iterable : Symbol(Iterable, Decl(lib.es2015.iterable.d.ts, --, --))
|
||||
|
||||
;(function(...rest) {})(...itNum)
|
||||
>rest : Symbol(rest, Decl(argumentsSpreadRestIterables.tsx, 2, 11))
|
||||
>itNum : Symbol(itNum, Decl(argumentsSpreadRestIterables.tsx, 0, 13))
|
||||
|
||||
;(function(a, ...rest) {})('', ...itNum)
|
||||
>a : Symbol(a, Decl(argumentsSpreadRestIterables.tsx, 3, 11))
|
||||
>rest : Symbol(rest, Decl(argumentsSpreadRestIterables.tsx, 3, 13))
|
||||
>itNum : Symbol(itNum, Decl(argumentsSpreadRestIterables.tsx, 0, 13))
|
||||
|
||||
;(function(a, ...rest) {})('', true, ...itNum)
|
||||
>a : Symbol(a, Decl(argumentsSpreadRestIterables.tsx, 4, 11))
|
||||
>rest : Symbol(rest, Decl(argumentsSpreadRestIterables.tsx, 4, 13))
|
||||
>itNum : Symbol(itNum, Decl(argumentsSpreadRestIterables.tsx, 0, 13))
|
||||
|
||||
declare function fn1<const T extends readonly unknown[]>(...args: T): T;
|
||||
>fn1 : Symbol(fn1, Decl(argumentsSpreadRestIterables.tsx, 4, 46))
|
||||
>T : Symbol(T, Decl(argumentsSpreadRestIterables.tsx, 6, 21))
|
||||
>args : Symbol(args, Decl(argumentsSpreadRestIterables.tsx, 6, 57))
|
||||
>T : Symbol(T, Decl(argumentsSpreadRestIterables.tsx, 6, 21))
|
||||
>T : Symbol(T, Decl(argumentsSpreadRestIterables.tsx, 6, 21))
|
||||
|
||||
const res1 = fn1(..."hello");
|
||||
>res1 : Symbol(res1, Decl(argumentsSpreadRestIterables.tsx, 7, 5))
|
||||
>fn1 : Symbol(fn1, Decl(argumentsSpreadRestIterables.tsx, 4, 46))
|
||||
|
||||
const res2 = fn1(...itNum);
|
||||
>res2 : Symbol(res2, Decl(argumentsSpreadRestIterables.tsx, 8, 5))
|
||||
>fn1 : Symbol(fn1, Decl(argumentsSpreadRestIterables.tsx, 4, 46))
|
||||
>itNum : Symbol(itNum, Decl(argumentsSpreadRestIterables.tsx, 0, 13))
|
||||
|
||||
const res3 = fn1(true, ..."hello");
|
||||
>res3 : Symbol(res3, Decl(argumentsSpreadRestIterables.tsx, 9, 5))
|
||||
>fn1 : Symbol(fn1, Decl(argumentsSpreadRestIterables.tsx, 4, 46))
|
||||
|
||||
const res4 = fn1(true, ...itNum);
|
||||
>res4 : Symbol(res4, Decl(argumentsSpreadRestIterables.tsx, 10, 5))
|
||||
>fn1 : Symbol(fn1, Decl(argumentsSpreadRestIterables.tsx, 4, 46))
|
||||
>itNum : Symbol(itNum, Decl(argumentsSpreadRestIterables.tsx, 0, 13))
|
||||
|
||||
// repro from #52781
|
||||
declare function foo<T extends unknown[]>(...args: T): T;
|
||||
>foo : Symbol(foo, Decl(argumentsSpreadRestIterables.tsx, 10, 33))
|
||||
>T : Symbol(T, Decl(argumentsSpreadRestIterables.tsx, 13, 21))
|
||||
>args : Symbol(args, Decl(argumentsSpreadRestIterables.tsx, 13, 42))
|
||||
>T : Symbol(T, Decl(argumentsSpreadRestIterables.tsx, 13, 21))
|
||||
>T : Symbol(T, Decl(argumentsSpreadRestIterables.tsx, 13, 21))
|
||||
|
||||
const p1 = foo(..."hello");
|
||||
>p1 : Symbol(p1, Decl(argumentsSpreadRestIterables.tsx, 14, 5))
|
||||
>foo : Symbol(foo, Decl(argumentsSpreadRestIterables.tsx, 10, 33))
|
||||
|
||||
const p2 = foo(...itNum);
|
||||
>p2 : Symbol(p2, Decl(argumentsSpreadRestIterables.tsx, 15, 5))
|
||||
>foo : Symbol(foo, Decl(argumentsSpreadRestIterables.tsx, 10, 33))
|
||||
>itNum : Symbol(itNum, Decl(argumentsSpreadRestIterables.tsx, 0, 13))
|
||||
|
||||
const p3 = foo(true, ..."hello");
|
||||
>p3 : Symbol(p3, Decl(argumentsSpreadRestIterables.tsx, 16, 5))
|
||||
>foo : Symbol(foo, Decl(argumentsSpreadRestIterables.tsx, 10, 33))
|
||||
|
||||
const p4 = foo(true, ...itNum);
|
||||
>p4 : Symbol(p4, Decl(argumentsSpreadRestIterables.tsx, 17, 5))
|
||||
>foo : Symbol(foo, Decl(argumentsSpreadRestIterables.tsx, 10, 33))
|
||||
>itNum : Symbol(itNum, Decl(argumentsSpreadRestIterables.tsx, 0, 13))
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
=== tests/cases/compiler/argumentsSpreadRestIterables.tsx ===
|
||||
declare const itNum: Iterable<number>
|
||||
>itNum : Iterable<number>
|
||||
|
||||
;(function(...rest) {})(...itNum)
|
||||
>(function(...rest) {})(...itNum) : void
|
||||
>(function(...rest) {}) : (...rest: number[]) => void
|
||||
>function(...rest) {} : (...rest: number[]) => void
|
||||
>rest : number[]
|
||||
>...itNum : number
|
||||
>itNum : Iterable<number>
|
||||
|
||||
;(function(a, ...rest) {})('', ...itNum)
|
||||
>(function(a, ...rest) {})('', ...itNum) : void
|
||||
>(function(a, ...rest) {}) : (a: string, ...rest: number[]) => void
|
||||
>function(a, ...rest) {} : (a: string, ...rest: number[]) => void
|
||||
>a : string
|
||||
>rest : number[]
|
||||
>'' : ""
|
||||
>...itNum : number
|
||||
>itNum : Iterable<number>
|
||||
|
||||
;(function(a, ...rest) {})('', true, ...itNum)
|
||||
>(function(a, ...rest) {})('', true, ...itNum) : void
|
||||
>(function(a, ...rest) {}) : (a: string, rest_0: boolean, ...rest_1: number[]) => void
|
||||
>function(a, ...rest) {} : (a: string, rest_0: boolean, ...rest_1: number[]) => void
|
||||
>a : string
|
||||
>rest : [boolean, ...number[]]
|
||||
>'' : ""
|
||||
>true : true
|
||||
>...itNum : number
|
||||
>itNum : Iterable<number>
|
||||
|
||||
declare function fn1<const T extends readonly unknown[]>(...args: T): T;
|
||||
>fn1 : <const T extends readonly unknown[]>(...args: T) => T
|
||||
>args : T
|
||||
|
||||
const res1 = fn1(..."hello");
|
||||
>res1 : readonly string[]
|
||||
>fn1(..."hello") : readonly string[]
|
||||
>fn1 : <const T extends readonly unknown[]>(...args: T) => T
|
||||
>..."hello" : string
|
||||
>"hello" : "hello"
|
||||
|
||||
const res2 = fn1(...itNum);
|
||||
>res2 : readonly number[]
|
||||
>fn1(...itNum) : readonly number[]
|
||||
>fn1 : <const T extends readonly unknown[]>(...args: T) => T
|
||||
>...itNum : number
|
||||
>itNum : Iterable<number>
|
||||
|
||||
const res3 = fn1(true, ..."hello");
|
||||
>res3 : readonly [true, ...string[]]
|
||||
>fn1(true, ..."hello") : readonly [true, ...string[]]
|
||||
>fn1 : <const T extends readonly unknown[]>(...args: T) => T
|
||||
>true : true
|
||||
>..."hello" : string
|
||||
>"hello" : "hello"
|
||||
|
||||
const res4 = fn1(true, ...itNum);
|
||||
>res4 : readonly [true, ...number[]]
|
||||
>fn1(true, ...itNum) : readonly [true, ...number[]]
|
||||
>fn1 : <const T extends readonly unknown[]>(...args: T) => T
|
||||
>true : true
|
||||
>...itNum : number
|
||||
>itNum : Iterable<number>
|
||||
|
||||
// repro from #52781
|
||||
declare function foo<T extends unknown[]>(...args: T): T;
|
||||
>foo : <T extends unknown[]>(...args: T) => T
|
||||
>args : T
|
||||
|
||||
const p1 = foo(..."hello");
|
||||
>p1 : string[]
|
||||
>foo(..."hello") : string[]
|
||||
>foo : <T extends unknown[]>(...args: T) => T
|
||||
>..."hello" : string
|
||||
>"hello" : "hello"
|
||||
|
||||
const p2 = foo(...itNum);
|
||||
>p2 : number[]
|
||||
>foo(...itNum) : number[]
|
||||
>foo : <T extends unknown[]>(...args: T) => T
|
||||
>...itNum : number
|
||||
>itNum : Iterable<number>
|
||||
|
||||
const p3 = foo(true, ..."hello");
|
||||
>p3 : [boolean, ...string[]]
|
||||
>foo(true, ..."hello") : [boolean, ...string[]]
|
||||
>foo : <T extends unknown[]>(...args: T) => T
|
||||
>true : true
|
||||
>..."hello" : string
|
||||
>"hello" : "hello"
|
||||
|
||||
const p4 = foo(true, ...itNum);
|
||||
>p4 : [boolean, ...number[]]
|
||||
>foo(true, ...itNum) : [boolean, ...number[]]
|
||||
>foo : <T extends unknown[]>(...args: T) => T
|
||||
>true : true
|
||||
>...itNum : number
|
||||
>itNum : Iterable<number>
|
||||
|
||||
22
tests/cases/compiler/argumentsSpreadRestIterables.tsx
Normal file
22
tests/cases/compiler/argumentsSpreadRestIterables.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
// @strict: true
|
||||
// @noEmit: true
|
||||
// @target: es5, esnext
|
||||
|
||||
declare const itNum: Iterable<number>
|
||||
|
||||
;(function(...rest) {})(...itNum)
|
||||
;(function(a, ...rest) {})('', ...itNum)
|
||||
;(function(a, ...rest) {})('', true, ...itNum)
|
||||
|
||||
declare function fn1<const T extends readonly unknown[]>(...args: T): T;
|
||||
const res1 = fn1(..."hello");
|
||||
const res2 = fn1(...itNum);
|
||||
const res3 = fn1(true, ..."hello");
|
||||
const res4 = fn1(true, ...itNum);
|
||||
|
||||
// repro from #52781
|
||||
declare function foo<T extends unknown[]>(...args: T): T;
|
||||
const p1 = foo(..."hello");
|
||||
const p2 = foo(...itNum);
|
||||
const p3 = foo(true, ..."hello");
|
||||
const p4 = foo(true, ...itNum);
|
||||
Reference in New Issue
Block a user