Merge pull request #25408 from Microsoft/contextualTupleTypes

Infer tuple types for contextually typed rest parameters
This commit is contained in:
Anders Hejlsberg 2018-07-03 14:02:48 -10:00 committed by GitHub
commit eb7ff43f95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 1125 additions and 104 deletions

View File

@ -12467,22 +12467,7 @@ namespace ts {
callback(getTypeAtPosition(source, i), getTypeAtPosition(target, i));
}
if (targetRestTypeVariable) {
const sourceRestTypeVariable = getRestTypeParameter(source);
if (sourceRestTypeVariable && paramCount === sourceCount - 1) {
callback(sourceRestTypeVariable, targetRestTypeVariable);
}
else {
const types = [];
const names = [];
for (let i = paramCount; i < maxCount; i++) {
types.push(getTypeAtPosition(source, i));
names.push(getParameterNameAtPosition(source, i));
}
const minArgumentCount = getMinArgumentCount(source);
const minLength = minArgumentCount < paramCount ? 0 : minArgumentCount - paramCount;
const rest = createTupleType(types, minLength, sourceHasRest, names);
callback(rest, targetRestTypeVariable);
}
callback(getRestTypeAtPosition(source, paramCount), targetRestTypeVariable);
}
}
@ -15284,43 +15269,35 @@ namespace ts {
}
const iife = getImmediatelyInvokedFunctionExpression(func);
if (iife && iife.arguments) {
const args = getEffectiveCallArguments(iife)!;
const indexOfParameter = func.parameters.indexOf(parameter);
if (parameter.dotDotDotToken) {
const restTypes: Type[] = [];
for (let i = indexOfParameter; i < iife.arguments.length; i++) {
restTypes.push(getWidenedLiteralType(checkExpression(iife.arguments[i])));
}
return restTypes.length ? createArrayType(getUnionType(restTypes)) : undefined;
return getSpreadArgumentType(iife, args, indexOfParameter, args.length, anyType, /*context*/ undefined);
}
const links = getNodeLinks(iife);
const cached = links.resolvedSignature;
links.resolvedSignature = anySignature;
const type = indexOfParameter < iife.arguments.length ?
getWidenedLiteralType(checkExpression(iife.arguments[indexOfParameter])) :
const type = indexOfParameter < args.length ?
getWidenedLiteralType(checkExpression(args[indexOfParameter])) :
parameter.initializer ? undefined : undefinedWideningType;
links.resolvedSignature = cached;
return type;
}
const contextualSignature = getContextualSignature(func);
if (contextualSignature) {
const funcHasRestParameters = hasRestParameter(func);
const len = func.parameters.length - (funcHasRestParameters ? 1 : 0);
const funcHasRestParameter = hasRestParameter(func);
const len = func.parameters.length - (funcHasRestParameter ? 1 : 0);
let indexOfParameter = func.parameters.indexOf(parameter);
if (getThisParameter(func) !== undefined && !contextualSignature.thisParameter) {
Debug.assert(indexOfParameter !== 0); // Otherwise we should not have called `getContextuallyTypedParameterType`.
indexOfParameter -= 1;
}
if (indexOfParameter < len) {
return getTypeAtPosition(contextualSignature, indexOfParameter);
}
// If last parameter is contextually rest parameter get its type
if (funcHasRestParameters &&
indexOfParameter === func.parameters.length - 1 &&
hasEffectiveRestParameter(contextualSignature) &&
func.parameters.length >= contextualSignature.parameters.length) {
return getTypeOfRestParameter(contextualSignature);
if (funcHasRestParameter && indexOfParameter === len) {
return getRestTypeAtPosition(contextualSignature, indexOfParameter);
}
}
}
@ -17895,7 +17872,7 @@ namespace ts {
}
}
function isSpreadArgument(arg: Expression | undefined) {
function isSpreadArgument(arg: Expression | undefined): arg is Expression {
return !!arg && (arg.kind === SyntaxKind.SpreadElement || arg.kind === SyntaxKind.SyntheticExpression && (<SyntheticExpression>arg).isSpread);
}
@ -18117,12 +18094,14 @@ namespace ts {
}
function getSpreadArgumentType(node: CallLikeExpression, args: ReadonlyArray<Expression>, index: number, argCount: number, restType: TypeParameter, context: InferenceContext | undefined) {
if (index === argCount - 1) {
const arg = getEffectiveArgument(node, args, index);
if (index >= argCount - 1) {
const arg = getEffectiveArgument(node, 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 checkExpressionWithContextualType((<SpreadElement>arg).expression, restType, context);
return arg.kind === SyntaxKind.SyntheticExpression ?
createArrayType((<SyntheticExpression>arg).type) :
checkExpressionWithContextualType((<SpreadElement>arg).expression, restType, context);
}
}
const contextualType = getIndexTypeOfType(restType, IndexKind.Number) || anyType;
@ -19651,6 +19630,27 @@ namespace ts {
return anyType;
}
function getRestTypeAtPosition(source: Signature, pos: number): Type {
const paramCount = getParameterCount(source);
const hasRest = hasEffectiveRestParameter(source);
if (hasRest && pos === paramCount - 1) {
const restTypeVariable = getRestTypeParameter(source);
if (restTypeVariable) {
return restTypeVariable;
}
}
const start = hasRest ? Math.min(pos, paramCount - 1) : pos;
const types = [];
const names = [];
for (let i = start; i < paramCount; i++) {
types.push(getTypeAtPosition(source, i));
names.push(getParameterNameAtPosition(source, i));
}
const minArgumentCount = getMinArgumentCount(source);
const minLength = minArgumentCount < start ? 0 : minArgumentCount - start;
return createTupleType(types, minLength, hasRest, names);
}
function getTypeOfRestParameter(signature: Signature) {
if (signature.hasRestParameter) {
const restType = getTypeOfSymbol(signature.parameters[signature.parameters.length - 1]);
@ -19744,11 +19744,11 @@ namespace ts {
assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType);
}
}
if (signature.hasRestParameter && context.hasRestParameter && signature.parameters.length >= context.parameters.length) {
if (signature.hasRestParameter) {
// parameter might be a transient symbol generated by use of `arguments` in the function body.
const parameter = last(signature.parameters);
if (isTransientSymbol(parameter) || !getEffectiveTypeAnnotationNode(<ParameterDeclaration>parameter.valueDeclaration)) {
const contextualParameterType = getTypeOfSymbol(last(context.parameters));
const contextualParameterType = getRestTypeAtPosition(context, len);
assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType);
}
}

View File

@ -101,12 +101,12 @@
// rest parameters
((...numbers) => numbers.every(n => n > 0))(5,6,7);
>((...numbers) => numbers.every(n => n > 0))(5,6,7) : boolean
>((...numbers) => numbers.every(n => n > 0)) : (...numbers: number[]) => boolean
>(...numbers) => numbers.every(n => n > 0) : (...numbers: number[]) => boolean
>numbers : number[]
>((...numbers) => numbers.every(n => n > 0)) : (numbers_0: number, numbers_1: number, numbers_2: number) => boolean
>(...numbers) => numbers.every(n => n > 0) : (numbers_0: number, numbers_1: number, numbers_2: number) => boolean
>numbers : [number, number, number]
>numbers.every(n => n > 0) : boolean
>numbers.every : (callbackfn: (value: number, index: number, array: number[]) => boolean, thisArg?: any) => boolean
>numbers : number[]
>numbers : [number, number, number]
>every : (callbackfn: (value: number, index: number, array: number[]) => boolean, thisArg?: any) => boolean
>n => n > 0 : (n: number) => boolean
>n : number
@ -119,12 +119,12 @@
((...mixed) => mixed.every(n => !!n))(5,'oops','oh no');
>((...mixed) => mixed.every(n => !!n))(5,'oops','oh no') : boolean
>((...mixed) => mixed.every(n => !!n)) : (...mixed: (string | number)[]) => boolean
>(...mixed) => mixed.every(n => !!n) : (...mixed: (string | number)[]) => boolean
>mixed : (string | number)[]
>((...mixed) => mixed.every(n => !!n)) : (mixed_0: number, mixed_1: string, mixed_2: string) => boolean
>(...mixed) => mixed.every(n => !!n) : (mixed_0: number, mixed_1: string, mixed_2: string) => boolean
>mixed : [number, string, string]
>mixed.every(n => !!n) : boolean
>mixed.every : (callbackfn: (value: string | number, index: number, array: (string | number)[]) => boolean, thisArg?: any) => boolean
>mixed : (string | number)[]
>mixed : [number, string, string]
>every : (callbackfn: (value: string | number, index: number, array: (string | number)[]) => boolean, thisArg?: any) => boolean
>n => !!n : (n: string | number) => boolean
>n : string | number
@ -137,31 +137,31 @@
((...noNumbers) => noNumbers.some(n => n > 0))();
>((...noNumbers) => noNumbers.some(n => n > 0))() : boolean
>((...noNumbers) => noNumbers.some(n => n > 0)) : (...noNumbers: any[]) => boolean
>(...noNumbers) => noNumbers.some(n => n > 0) : (...noNumbers: any[]) => boolean
>noNumbers : any[]
>((...noNumbers) => noNumbers.some(n => n > 0)) : () => boolean
>(...noNumbers) => noNumbers.some(n => n > 0) : () => boolean
>noNumbers : []
>noNumbers.some(n => n > 0) : boolean
>noNumbers.some : (callbackfn: (value: any, index: number, array: any[]) => boolean, thisArg?: any) => boolean
>noNumbers : any[]
>some : (callbackfn: (value: any, index: number, array: any[]) => boolean, thisArg?: any) => boolean
>n => n > 0 : (n: any) => boolean
>n : any
>noNumbers.some : (callbackfn: (value: never, index: number, array: never[]) => boolean, thisArg?: any) => boolean
>noNumbers : []
>some : (callbackfn: (value: never, index: number, array: never[]) => boolean, thisArg?: any) => boolean
>n => n > 0 : (n: never) => boolean
>n : never
>n > 0 : boolean
>n : any
>n : never
>0 : 0
((first, ...rest) => first ? [] : rest.map(n => n > 0))(8,9,10);
>((first, ...rest) => first ? [] : rest.map(n => n > 0))(8,9,10) : boolean[]
>((first, ...rest) => first ? [] : rest.map(n => n > 0)) : (first: number, ...rest: number[]) => boolean[]
>(first, ...rest) => first ? [] : rest.map(n => n > 0) : (first: number, ...rest: number[]) => boolean[]
>((first, ...rest) => first ? [] : rest.map(n => n > 0)) : (first: number, rest_0: number, rest_1: number) => boolean[]
>(first, ...rest) => first ? [] : rest.map(n => n > 0) : (first: number, rest_0: number, rest_1: number) => boolean[]
>first : number
>rest : number[]
>rest : [number, number]
>first ? [] : rest.map(n => n > 0) : boolean[]
>first : number
>[] : undefined[]
>rest.map(n => n > 0) : boolean[]
>rest.map : <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]
>rest : number[]
>rest : [number, number]
>map : <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]
>n => n > 0 : (n: number) => boolean
>n : number

View File

@ -101,12 +101,12 @@
// rest parameters
((...numbers) => numbers.every(n => n > 0))(5,6,7);
>((...numbers) => numbers.every(n => n > 0))(5,6,7) : boolean
>((...numbers) => numbers.every(n => n > 0)) : (...numbers: number[]) => boolean
>(...numbers) => numbers.every(n => n > 0) : (...numbers: number[]) => boolean
>numbers : number[]
>((...numbers) => numbers.every(n => n > 0)) : (numbers_0: number, numbers_1: number, numbers_2: number) => boolean
>(...numbers) => numbers.every(n => n > 0) : (numbers_0: number, numbers_1: number, numbers_2: number) => boolean
>numbers : [number, number, number]
>numbers.every(n => n > 0) : boolean
>numbers.every : (callbackfn: (value: number, index: number, array: number[]) => boolean, thisArg?: any) => boolean
>numbers : number[]
>numbers : [number, number, number]
>every : (callbackfn: (value: number, index: number, array: number[]) => boolean, thisArg?: any) => boolean
>n => n > 0 : (n: number) => boolean
>n : number
@ -119,12 +119,12 @@
((...mixed) => mixed.every(n => !!n))(5,'oops','oh no');
>((...mixed) => mixed.every(n => !!n))(5,'oops','oh no') : boolean
>((...mixed) => mixed.every(n => !!n)) : (...mixed: (string | number)[]) => boolean
>(...mixed) => mixed.every(n => !!n) : (...mixed: (string | number)[]) => boolean
>mixed : (string | number)[]
>((...mixed) => mixed.every(n => !!n)) : (mixed_0: number, mixed_1: string, mixed_2: string) => boolean
>(...mixed) => mixed.every(n => !!n) : (mixed_0: number, mixed_1: string, mixed_2: string) => boolean
>mixed : [number, string, string]
>mixed.every(n => !!n) : boolean
>mixed.every : (callbackfn: (value: string | number, index: number, array: (string | number)[]) => boolean, thisArg?: any) => boolean
>mixed : (string | number)[]
>mixed : [number, string, string]
>every : (callbackfn: (value: string | number, index: number, array: (string | number)[]) => boolean, thisArg?: any) => boolean
>n => !!n : (n: string | number) => boolean
>n : string | number
@ -137,31 +137,31 @@
((...noNumbers) => noNumbers.some(n => n > 0))();
>((...noNumbers) => noNumbers.some(n => n > 0))() : boolean
>((...noNumbers) => noNumbers.some(n => n > 0)) : (...noNumbers: any[]) => boolean
>(...noNumbers) => noNumbers.some(n => n > 0) : (...noNumbers: any[]) => boolean
>noNumbers : any[]
>((...noNumbers) => noNumbers.some(n => n > 0)) : () => boolean
>(...noNumbers) => noNumbers.some(n => n > 0) : () => boolean
>noNumbers : []
>noNumbers.some(n => n > 0) : boolean
>noNumbers.some : (callbackfn: (value: any, index: number, array: any[]) => boolean, thisArg?: any) => boolean
>noNumbers : any[]
>some : (callbackfn: (value: any, index: number, array: any[]) => boolean, thisArg?: any) => boolean
>n => n > 0 : (n: any) => boolean
>n : any
>noNumbers.some : (callbackfn: (value: never, index: number, array: never[]) => boolean, thisArg?: any) => boolean
>noNumbers : []
>some : (callbackfn: (value: never, index: number, array: never[]) => boolean, thisArg?: any) => boolean
>n => n > 0 : (n: never) => boolean
>n : never
>n > 0 : boolean
>n : any
>n : never
>0 : 0
((first, ...rest) => first ? [] : rest.map(n => n > 0))(8,9,10);
>((first, ...rest) => first ? [] : rest.map(n => n > 0))(8,9,10) : boolean[]
>((first, ...rest) => first ? [] : rest.map(n => n > 0)) : (first: number, ...rest: number[]) => boolean[]
>(first, ...rest) => first ? [] : rest.map(n => n > 0) : (first: number, ...rest: number[]) => boolean[]
>((first, ...rest) => first ? [] : rest.map(n => n > 0)) : (first: number, rest_0: number, rest_1: number) => boolean[]
>(first, ...rest) => first ? [] : rest.map(n => n > 0) : (first: number, rest_0: number, rest_1: number) => boolean[]
>first : number
>rest : number[]
>rest : [number, number]
>first ? [] : rest.map(n => n > 0) : boolean[]
>first : number
>[] : never[]
>rest.map(n => n > 0) : boolean[]
>rest.map : <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]
>rest : number[]
>rest : [number, number]
>map : <U>(callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[]
>n => n > 0 : (n: number) => boolean
>n : number

View File

@ -37,22 +37,22 @@ var x = function (str = "hello", ...rest) { }
var y = (function (num = 10, boo = false, ...rest) { })()
>y : void
>(function (num = 10, boo = false, ...rest) { })() : void
>(function (num = 10, boo = false, ...rest) { }) : (num?: number, boo?: boolean, ...rest: any[]) => void
>function (num = 10, boo = false, ...rest) { } : (num?: number, boo?: boolean, ...rest: any[]) => void
>(function (num = 10, boo = false, ...rest) { }) : (num?: number, boo?: boolean) => void
>function (num = 10, boo = false, ...rest) { } : (num?: number, boo?: boolean) => void
>num : number
>10 : 10
>boo : boolean
>false : false
>rest : any[]
>rest : []
var z = (function (num: number, boo = false, ...rest) { })(10)
>z : void
>(function (num: number, boo = false, ...rest) { })(10) : void
>(function (num: number, boo = false, ...rest) { }) : (num: number, boo?: boolean, ...rest: any[]) => void
>function (num: number, boo = false, ...rest) { } : (num: number, boo?: boolean, ...rest: any[]) => void
>(function (num: number, boo = false, ...rest) { }) : (num: number, boo?: boolean) => void
>function (num: number, boo = false, ...rest) { } : (num: number, boo?: boolean) => void
>num : number
>boo : boolean
>false : false
>rest : any[]
>rest : []
>10 : 10

View File

@ -37,22 +37,22 @@ var x = function (str = "hello", ...rest) { }
var y = (function (num = 10, boo = false, ...rest) { })()
>y : void
>(function (num = 10, boo = false, ...rest) { })() : void
>(function (num = 10, boo = false, ...rest) { }) : (num?: number, boo?: boolean, ...rest: any[]) => void
>function (num = 10, boo = false, ...rest) { } : (num?: number, boo?: boolean, ...rest: any[]) => void
>(function (num = 10, boo = false, ...rest) { }) : (num?: number, boo?: boolean) => void
>function (num = 10, boo = false, ...rest) { } : (num?: number, boo?: boolean) => void
>num : number
>10 : 10
>boo : boolean
>false : false
>rest : any[]
>rest : []
var z = (function (num: number, boo = false, ...rest) { })(10)
>z : void
>(function (num: number, boo = false, ...rest) { })(10) : void
>(function (num: number, boo = false, ...rest) { }) : (num: number, boo?: boolean, ...rest: any[]) => void
>function (num: number, boo = false, ...rest) { } : (num: number, boo?: boolean, ...rest: any[]) => void
>(function (num: number, boo = false, ...rest) { }) : (num: number, boo?: boolean) => void
>function (num: number, boo = false, ...rest) { } : (num: number, boo?: boolean) => void
>num : number
>boo : boolean
>false : false
>rest : any[]
>rest : []
>10 : 10

View File

@ -18,7 +18,7 @@ var funcExp2 = function (...rest) { }
var funcExp3 = (function (...rest) { })()
>funcExp3 : void
>(function (...rest) { })() : void
>(function (...rest) { }) : (...rest: any[]) => void
>function (...rest) { } : (...rest: any[]) => void
>rest : any[]
>(function (...rest) { }) : () => void
>function (...rest) { } : () => void
>rest : []

View File

@ -18,7 +18,7 @@ var funcExp2 = function (...rest) { }
var funcExp3 = (function (...rest) { })()
>funcExp3 : void
>(function (...rest) { })() : void
>(function (...rest) { }) : (...rest: any[]) => void
>function (...rest) { } : (...rest: any[]) => void
>rest : any[]
>(function (...rest) { }) : () => void
>function (...rest) { } : () => void
>rest : []

View File

@ -119,12 +119,12 @@ testRest((t1, t2: D, t3) => {})
>t3 : D
testRest((t2: D, ...t3) => {})
>testRest((t2: D, ...t3) => {}) : any
>testRest((t2: D, ...t3) => {}) : D
>testRest : <T extends C>(a: (t: T, t1: T, ...ts: T[]) => void) => T
>(t2: D, ...t3) => {} : (t2: D, ...t3: any[]) => void
>(t2: D, ...t3) => {} : (t2: D, t1: D, ...ts: D[]) => void
>t2 : D
>D : D
>t3 : any[]
>t3 : [D, ...D[]]
testRest((t2, ...t3: D[]) => {})
>testRest((t2, ...t3: D[]) => {}) : C

View File

@ -0,0 +1,288 @@
//// [restTuplesFromContextualTypes.ts]
declare const t1: [number, boolean, string];
(function (a, b, c){})(...t1);
(function (...x){})(...t1);
(function (a, ...x){})(...t1);
(function (a, b, ...x){})(...t1);
(function (a, b, c, ...x){})(...t1);
declare function f1(cb: (...args: typeof t1) => void): void;
f1((a, b, c) => {})
f1((...x) => {})
f1((a, ...x) => {})
f1((a, b, ...x) => {})
f1((a, b, c, ...x) => {})
declare const t2: [number, boolean, ...string[]];
(function (a, b, c){})(...t2);
(function (...x){})(...t2);
(function (a, ...x){})(...t2);
(function (a, b, ...x){})(...t2);
(function (a, b, c, ...x){})(...t2);
declare function f2(cb: (...args: typeof t2) => void): void;
f2((a, b, c) => {})
f2((...x) => {})
f2((a, ...x) => {})
f2((a, b, ...x) => {})
f2((a, b, c, ...x) => {})
declare const t3: [boolean, ...string[]];
(function (a, b, c){})(1, ...t3);
(function (...x){})(1, ...t3);
(function (a, ...x){})(1, ...t3);
(function (a, b, ...x){})(1, ...t3);
(function (a, b, c, ...x){})(1, ...t3);
declare function f3(cb: (x: number, ...args: typeof t3) => void): void;
f3((a, b, c) => {})
f3((...x) => {})
f3((a, ...x) => {})
f3((a, b, ...x) => {})
f3((a, b, c, ...x) => {})
function f4<T extends any[]>(t: T) {
(function(...x){})(...t);
(function(a, ...x){})(1, ...t);
(function(a, ...x){})(1, 2, ...t);
function f(cb: (x: number, ...args: T) => void) {}
f((...x) => {});
f((a, ...x) => {});
f((a, b, ...x) => {});
}
// Repro from #25288
declare var tuple: [number, string];
(function foo(a, b){}(...tuple));
// Repro from #25289
declare function take(cb: (a: number, b: string) => void): void;
(function foo(...rest){}(1, ''));
take(function(...rest){});
//// [restTuplesFromContextualTypes.js]
"use strict";
(function (a, b, c) { }).apply(void 0, t1);
(function () {
var x = [];
for (var _i = 0; _i < arguments.length; _i++) {
x[_i] = arguments[_i];
}
}).apply(void 0, t1);
(function (a) {
var x = [];
for (var _i = 1; _i < arguments.length; _i++) {
x[_i - 1] = arguments[_i];
}
}).apply(void 0, t1);
(function (a, b) {
var x = [];
for (var _i = 2; _i < arguments.length; _i++) {
x[_i - 2] = arguments[_i];
}
}).apply(void 0, t1);
(function (a, b, c) {
var x = [];
for (var _i = 3; _i < arguments.length; _i++) {
x[_i - 3] = arguments[_i];
}
}).apply(void 0, t1);
f1(function (a, b, c) { });
f1(function () {
var x = [];
for (var _i = 0; _i < arguments.length; _i++) {
x[_i] = arguments[_i];
}
});
f1(function (a) {
var x = [];
for (var _i = 1; _i < arguments.length; _i++) {
x[_i - 1] = arguments[_i];
}
});
f1(function (a, b) {
var x = [];
for (var _i = 2; _i < arguments.length; _i++) {
x[_i - 2] = arguments[_i];
}
});
f1(function (a, b, c) {
var x = [];
for (var _i = 3; _i < arguments.length; _i++) {
x[_i - 3] = arguments[_i];
}
});
(function (a, b, c) { }).apply(void 0, t2);
(function () {
var x = [];
for (var _i = 0; _i < arguments.length; _i++) {
x[_i] = arguments[_i];
}
}).apply(void 0, t2);
(function (a) {
var x = [];
for (var _i = 1; _i < arguments.length; _i++) {
x[_i - 1] = arguments[_i];
}
}).apply(void 0, t2);
(function (a, b) {
var x = [];
for (var _i = 2; _i < arguments.length; _i++) {
x[_i - 2] = arguments[_i];
}
}).apply(void 0, t2);
(function (a, b, c) {
var x = [];
for (var _i = 3; _i < arguments.length; _i++) {
x[_i - 3] = arguments[_i];
}
}).apply(void 0, t2);
f2(function (a, b, c) { });
f2(function () {
var x = [];
for (var _i = 0; _i < arguments.length; _i++) {
x[_i] = arguments[_i];
}
});
f2(function (a) {
var x = [];
for (var _i = 1; _i < arguments.length; _i++) {
x[_i - 1] = arguments[_i];
}
});
f2(function (a, b) {
var x = [];
for (var _i = 2; _i < arguments.length; _i++) {
x[_i - 2] = arguments[_i];
}
});
f2(function (a, b, c) {
var x = [];
for (var _i = 3; _i < arguments.length; _i++) {
x[_i - 3] = arguments[_i];
}
});
(function (a, b, c) { }).apply(void 0, [1].concat(t3));
(function () {
var x = [];
for (var _i = 0; _i < arguments.length; _i++) {
x[_i] = arguments[_i];
}
}).apply(void 0, [1].concat(t3));
(function (a) {
var x = [];
for (var _i = 1; _i < arguments.length; _i++) {
x[_i - 1] = arguments[_i];
}
}).apply(void 0, [1].concat(t3));
(function (a, b) {
var x = [];
for (var _i = 2; _i < arguments.length; _i++) {
x[_i - 2] = arguments[_i];
}
}).apply(void 0, [1].concat(t3));
(function (a, b, c) {
var x = [];
for (var _i = 3; _i < arguments.length; _i++) {
x[_i - 3] = arguments[_i];
}
}).apply(void 0, [1].concat(t3));
f3(function (a, b, c) { });
f3(function () {
var x = [];
for (var _i = 0; _i < arguments.length; _i++) {
x[_i] = arguments[_i];
}
});
f3(function (a) {
var x = [];
for (var _i = 1; _i < arguments.length; _i++) {
x[_i - 1] = arguments[_i];
}
});
f3(function (a, b) {
var x = [];
for (var _i = 2; _i < arguments.length; _i++) {
x[_i - 2] = arguments[_i];
}
});
f3(function (a, b, c) {
var x = [];
for (var _i = 3; _i < arguments.length; _i++) {
x[_i - 3] = arguments[_i];
}
});
function f4(t) {
(function () {
var x = [];
for (var _i = 0; _i < arguments.length; _i++) {
x[_i] = arguments[_i];
}
}).apply(void 0, t);
(function (a) {
var x = [];
for (var _i = 1; _i < arguments.length; _i++) {
x[_i - 1] = arguments[_i];
}
}).apply(void 0, [1].concat(t));
(function (a) {
var x = [];
for (var _i = 1; _i < arguments.length; _i++) {
x[_i - 1] = arguments[_i];
}
}).apply(void 0, [1, 2].concat(t));
function f(cb) { }
f(function () {
var x = [];
for (var _i = 0; _i < arguments.length; _i++) {
x[_i] = arguments[_i];
}
});
f(function (a) {
var x = [];
for (var _i = 1; _i < arguments.length; _i++) {
x[_i - 1] = arguments[_i];
}
});
f(function (a, b) {
var x = [];
for (var _i = 2; _i < arguments.length; _i++) {
x[_i - 2] = arguments[_i];
}
});
}
(function foo(a, b) { }.apply(void 0, tuple));
(function foo() {
var rest = [];
for (var _i = 0; _i < arguments.length; _i++) {
rest[_i] = arguments[_i];
}
}(1, ''));
take(function () {
var rest = [];
for (var _i = 0; _i < arguments.length; _i++) {
rest[_i] = arguments[_i];
}
});
//// [restTuplesFromContextualTypes.d.ts]
declare const t1: [number, boolean, string];
declare function f1(cb: (...args: typeof t1) => void): void;
declare const t2: [number, boolean, ...string[]];
declare function f2(cb: (...args: typeof t2) => void): void;
declare const t3: [boolean, ...string[]];
declare function f3(cb: (x: number, ...args: typeof t3) => void): void;
declare function f4<T extends any[]>(t: T): void;
declare var tuple: [number, string];
declare function take(cb: (a: number, b: string) => void): void;

View File

@ -0,0 +1,267 @@
=== tests/cases/conformance/types/rest/restTuplesFromContextualTypes.ts ===
declare const t1: [number, boolean, string];
>t1 : Symbol(t1, Decl(restTuplesFromContextualTypes.ts, 0, 13))
(function (a, b, c){})(...t1);
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 2, 11))
>b : Symbol(b, Decl(restTuplesFromContextualTypes.ts, 2, 13))
>c : Symbol(c, Decl(restTuplesFromContextualTypes.ts, 2, 16))
>t1 : Symbol(t1, Decl(restTuplesFromContextualTypes.ts, 0, 13))
(function (...x){})(...t1);
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 3, 11))
>t1 : Symbol(t1, Decl(restTuplesFromContextualTypes.ts, 0, 13))
(function (a, ...x){})(...t1);
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 4, 11))
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 4, 13))
>t1 : Symbol(t1, Decl(restTuplesFromContextualTypes.ts, 0, 13))
(function (a, b, ...x){})(...t1);
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 5, 11))
>b : Symbol(b, Decl(restTuplesFromContextualTypes.ts, 5, 13))
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 5, 16))
>t1 : Symbol(t1, Decl(restTuplesFromContextualTypes.ts, 0, 13))
(function (a, b, c, ...x){})(...t1);
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 6, 11))
>b : Symbol(b, Decl(restTuplesFromContextualTypes.ts, 6, 13))
>c : Symbol(c, Decl(restTuplesFromContextualTypes.ts, 6, 16))
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 6, 19))
>t1 : Symbol(t1, Decl(restTuplesFromContextualTypes.ts, 0, 13))
declare function f1(cb: (...args: typeof t1) => void): void;
>f1 : Symbol(f1, Decl(restTuplesFromContextualTypes.ts, 6, 36))
>cb : Symbol(cb, Decl(restTuplesFromContextualTypes.ts, 8, 20))
>args : Symbol(args, Decl(restTuplesFromContextualTypes.ts, 8, 25))
>t1 : Symbol(t1, Decl(restTuplesFromContextualTypes.ts, 0, 13))
f1((a, b, c) => {})
>f1 : Symbol(f1, Decl(restTuplesFromContextualTypes.ts, 6, 36))
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 10, 4))
>b : Symbol(b, Decl(restTuplesFromContextualTypes.ts, 10, 6))
>c : Symbol(c, Decl(restTuplesFromContextualTypes.ts, 10, 9))
f1((...x) => {})
>f1 : Symbol(f1, Decl(restTuplesFromContextualTypes.ts, 6, 36))
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 11, 4))
f1((a, ...x) => {})
>f1 : Symbol(f1, Decl(restTuplesFromContextualTypes.ts, 6, 36))
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 12, 4))
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 12, 6))
f1((a, b, ...x) => {})
>f1 : Symbol(f1, Decl(restTuplesFromContextualTypes.ts, 6, 36))
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 13, 4))
>b : Symbol(b, Decl(restTuplesFromContextualTypes.ts, 13, 6))
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 13, 9))
f1((a, b, c, ...x) => {})
>f1 : Symbol(f1, Decl(restTuplesFromContextualTypes.ts, 6, 36))
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 14, 4))
>b : Symbol(b, Decl(restTuplesFromContextualTypes.ts, 14, 6))
>c : Symbol(c, Decl(restTuplesFromContextualTypes.ts, 14, 9))
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 14, 12))
declare const t2: [number, boolean, ...string[]];
>t2 : Symbol(t2, Decl(restTuplesFromContextualTypes.ts, 16, 13))
(function (a, b, c){})(...t2);
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 18, 11))
>b : Symbol(b, Decl(restTuplesFromContextualTypes.ts, 18, 13))
>c : Symbol(c, Decl(restTuplesFromContextualTypes.ts, 18, 16))
>t2 : Symbol(t2, Decl(restTuplesFromContextualTypes.ts, 16, 13))
(function (...x){})(...t2);
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 19, 11))
>t2 : Symbol(t2, Decl(restTuplesFromContextualTypes.ts, 16, 13))
(function (a, ...x){})(...t2);
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 20, 11))
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 20, 13))
>t2 : Symbol(t2, Decl(restTuplesFromContextualTypes.ts, 16, 13))
(function (a, b, ...x){})(...t2);
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 21, 11))
>b : Symbol(b, Decl(restTuplesFromContextualTypes.ts, 21, 13))
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 21, 16))
>t2 : Symbol(t2, Decl(restTuplesFromContextualTypes.ts, 16, 13))
(function (a, b, c, ...x){})(...t2);
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 22, 11))
>b : Symbol(b, Decl(restTuplesFromContextualTypes.ts, 22, 13))
>c : Symbol(c, Decl(restTuplesFromContextualTypes.ts, 22, 16))
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 22, 19))
>t2 : Symbol(t2, Decl(restTuplesFromContextualTypes.ts, 16, 13))
declare function f2(cb: (...args: typeof t2) => void): void;
>f2 : Symbol(f2, Decl(restTuplesFromContextualTypes.ts, 22, 36))
>cb : Symbol(cb, Decl(restTuplesFromContextualTypes.ts, 24, 20))
>args : Symbol(args, Decl(restTuplesFromContextualTypes.ts, 24, 25))
>t2 : Symbol(t2, Decl(restTuplesFromContextualTypes.ts, 16, 13))
f2((a, b, c) => {})
>f2 : Symbol(f2, Decl(restTuplesFromContextualTypes.ts, 22, 36))
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 26, 4))
>b : Symbol(b, Decl(restTuplesFromContextualTypes.ts, 26, 6))
>c : Symbol(c, Decl(restTuplesFromContextualTypes.ts, 26, 9))
f2((...x) => {})
>f2 : Symbol(f2, Decl(restTuplesFromContextualTypes.ts, 22, 36))
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 27, 4))
f2((a, ...x) => {})
>f2 : Symbol(f2, Decl(restTuplesFromContextualTypes.ts, 22, 36))
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 28, 4))
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 28, 6))
f2((a, b, ...x) => {})
>f2 : Symbol(f2, Decl(restTuplesFromContextualTypes.ts, 22, 36))
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 29, 4))
>b : Symbol(b, Decl(restTuplesFromContextualTypes.ts, 29, 6))
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 29, 9))
f2((a, b, c, ...x) => {})
>f2 : Symbol(f2, Decl(restTuplesFromContextualTypes.ts, 22, 36))
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 30, 4))
>b : Symbol(b, Decl(restTuplesFromContextualTypes.ts, 30, 6))
>c : Symbol(c, Decl(restTuplesFromContextualTypes.ts, 30, 9))
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 30, 12))
declare const t3: [boolean, ...string[]];
>t3 : Symbol(t3, Decl(restTuplesFromContextualTypes.ts, 32, 13))
(function (a, b, c){})(1, ...t3);
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 34, 11))
>b : Symbol(b, Decl(restTuplesFromContextualTypes.ts, 34, 13))
>c : Symbol(c, Decl(restTuplesFromContextualTypes.ts, 34, 16))
>t3 : Symbol(t3, Decl(restTuplesFromContextualTypes.ts, 32, 13))
(function (...x){})(1, ...t3);
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 35, 11))
>t3 : Symbol(t3, Decl(restTuplesFromContextualTypes.ts, 32, 13))
(function (a, ...x){})(1, ...t3);
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 36, 11))
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 36, 13))
>t3 : Symbol(t3, Decl(restTuplesFromContextualTypes.ts, 32, 13))
(function (a, b, ...x){})(1, ...t3);
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 37, 11))
>b : Symbol(b, Decl(restTuplesFromContextualTypes.ts, 37, 13))
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 37, 16))
>t3 : Symbol(t3, Decl(restTuplesFromContextualTypes.ts, 32, 13))
(function (a, b, c, ...x){})(1, ...t3);
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 38, 11))
>b : Symbol(b, Decl(restTuplesFromContextualTypes.ts, 38, 13))
>c : Symbol(c, Decl(restTuplesFromContextualTypes.ts, 38, 16))
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 38, 19))
>t3 : Symbol(t3, Decl(restTuplesFromContextualTypes.ts, 32, 13))
declare function f3(cb: (x: number, ...args: typeof t3) => void): void;
>f3 : Symbol(f3, Decl(restTuplesFromContextualTypes.ts, 38, 39))
>cb : Symbol(cb, Decl(restTuplesFromContextualTypes.ts, 40, 20))
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 40, 25))
>args : Symbol(args, Decl(restTuplesFromContextualTypes.ts, 40, 35))
>t3 : Symbol(t3, Decl(restTuplesFromContextualTypes.ts, 32, 13))
f3((a, b, c) => {})
>f3 : Symbol(f3, Decl(restTuplesFromContextualTypes.ts, 38, 39))
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 42, 4))
>b : Symbol(b, Decl(restTuplesFromContextualTypes.ts, 42, 6))
>c : Symbol(c, Decl(restTuplesFromContextualTypes.ts, 42, 9))
f3((...x) => {})
>f3 : Symbol(f3, Decl(restTuplesFromContextualTypes.ts, 38, 39))
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 43, 4))
f3((a, ...x) => {})
>f3 : Symbol(f3, Decl(restTuplesFromContextualTypes.ts, 38, 39))
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 44, 4))
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 44, 6))
f3((a, b, ...x) => {})
>f3 : Symbol(f3, Decl(restTuplesFromContextualTypes.ts, 38, 39))
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 45, 4))
>b : Symbol(b, Decl(restTuplesFromContextualTypes.ts, 45, 6))
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 45, 9))
f3((a, b, c, ...x) => {})
>f3 : Symbol(f3, Decl(restTuplesFromContextualTypes.ts, 38, 39))
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 46, 4))
>b : Symbol(b, Decl(restTuplesFromContextualTypes.ts, 46, 6))
>c : Symbol(c, Decl(restTuplesFromContextualTypes.ts, 46, 9))
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 46, 12))
function f4<T extends any[]>(t: T) {
>f4 : Symbol(f4, Decl(restTuplesFromContextualTypes.ts, 46, 25))
>T : Symbol(T, Decl(restTuplesFromContextualTypes.ts, 48, 12))
>t : Symbol(t, Decl(restTuplesFromContextualTypes.ts, 48, 29))
>T : Symbol(T, Decl(restTuplesFromContextualTypes.ts, 48, 12))
(function(...x){})(...t);
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 49, 14))
>t : Symbol(t, Decl(restTuplesFromContextualTypes.ts, 48, 29))
(function(a, ...x){})(1, ...t);
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 50, 14))
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 50, 16))
>t : Symbol(t, Decl(restTuplesFromContextualTypes.ts, 48, 29))
(function(a, ...x){})(1, 2, ...t);
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 51, 14))
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 51, 16))
>t : Symbol(t, Decl(restTuplesFromContextualTypes.ts, 48, 29))
function f(cb: (x: number, ...args: T) => void) {}
>f : Symbol(f, Decl(restTuplesFromContextualTypes.ts, 51, 38))
>cb : Symbol(cb, Decl(restTuplesFromContextualTypes.ts, 52, 15))
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 52, 20))
>args : Symbol(args, Decl(restTuplesFromContextualTypes.ts, 52, 30))
>T : Symbol(T, Decl(restTuplesFromContextualTypes.ts, 48, 12))
f((...x) => {});
>f : Symbol(f, Decl(restTuplesFromContextualTypes.ts, 51, 38))
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 53, 7))
f((a, ...x) => {});
>f : Symbol(f, Decl(restTuplesFromContextualTypes.ts, 51, 38))
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 54, 7))
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 54, 9))
f((a, b, ...x) => {});
>f : Symbol(f, Decl(restTuplesFromContextualTypes.ts, 51, 38))
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 55, 7))
>b : Symbol(b, Decl(restTuplesFromContextualTypes.ts, 55, 9))
>x : Symbol(x, Decl(restTuplesFromContextualTypes.ts, 55, 12))
}
// Repro from #25288
declare var tuple: [number, string];
>tuple : Symbol(tuple, Decl(restTuplesFromContextualTypes.ts, 60, 11))
(function foo(a, b){}(...tuple));
>foo : Symbol(foo, Decl(restTuplesFromContextualTypes.ts, 61, 1))
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 61, 14))
>b : Symbol(b, Decl(restTuplesFromContextualTypes.ts, 61, 16))
>tuple : Symbol(tuple, Decl(restTuplesFromContextualTypes.ts, 60, 11))
// Repro from #25289
declare function take(cb: (a: number, b: string) => void): void;
>take : Symbol(take, Decl(restTuplesFromContextualTypes.ts, 61, 33))
>cb : Symbol(cb, Decl(restTuplesFromContextualTypes.ts, 65, 22))
>a : Symbol(a, Decl(restTuplesFromContextualTypes.ts, 65, 27))
>b : Symbol(b, Decl(restTuplesFromContextualTypes.ts, 65, 37))
(function foo(...rest){}(1, ''));
>foo : Symbol(foo, Decl(restTuplesFromContextualTypes.ts, 67, 1))
>rest : Symbol(rest, Decl(restTuplesFromContextualTypes.ts, 67, 14))
take(function(...rest){});
>take : Symbol(take, Decl(restTuplesFromContextualTypes.ts, 61, 33))
>rest : Symbol(rest, Decl(restTuplesFromContextualTypes.ts, 68, 14))

View File

@ -0,0 +1,394 @@
=== tests/cases/conformance/types/rest/restTuplesFromContextualTypes.ts ===
declare const t1: [number, boolean, string];
>t1 : [number, boolean, string]
(function (a, b, c){})(...t1);
>(function (a, b, c){})(...t1) : void
>(function (a, b, c){}) : (a: number, b?: boolean, c?: string) => void
>function (a, b, c){} : (a: number, b?: boolean, c?: string) => void
>a : number
>b : boolean
>c : string
>...t1 : string | number | boolean
>t1 : [number, boolean, string]
(function (...x){})(...t1);
>(function (...x){})(...t1) : void
>(function (...x){}) : (x_0: number, x_1: boolean, x_2: string) => void
>function (...x){} : (x_0: number, x_1: boolean, x_2: string) => void
>x : [number, boolean, string]
>...t1 : string | number | boolean
>t1 : [number, boolean, string]
(function (a, ...x){})(...t1);
>(function (a, ...x){})(...t1) : void
>(function (a, ...x){}) : (a: number, x_0: boolean, x_1: string) => void
>function (a, ...x){} : (a: number, x_0: boolean, x_1: string) => void
>a : number
>x : [boolean, string]
>...t1 : string | number | boolean
>t1 : [number, boolean, string]
(function (a, b, ...x){})(...t1);
>(function (a, b, ...x){})(...t1) : void
>(function (a, b, ...x){}) : (a: number, b?: boolean, x_0: string) => void
>function (a, b, ...x){} : (a: number, b?: boolean, x_0: string) => void
>a : number
>b : boolean
>x : [string]
>...t1 : string | number | boolean
>t1 : [number, boolean, string]
(function (a, b, c, ...x){})(...t1);
>(function (a, b, c, ...x){})(...t1) : void
>(function (a, b, c, ...x){}) : (a: number, b?: boolean, c?: string) => void
>function (a, b, c, ...x){} : (a: number, b?: boolean, c?: string) => void
>a : number
>b : boolean
>c : string
>x : []
>...t1 : string | number | boolean
>t1 : [number, boolean, string]
declare function f1(cb: (...args: typeof t1) => void): void;
>f1 : (cb: (args_0: number, args_1: boolean, args_2: string) => void) => void
>cb : (args_0: number, args_1: boolean, args_2: string) => void
>args : [number, boolean, string]
>t1 : [number, boolean, string]
f1((a, b, c) => {})
>f1((a, b, c) => {}) : void
>f1 : (cb: (args_0: number, args_1: boolean, args_2: string) => void) => void
>(a, b, c) => {} : (a: number, b: boolean, c: string) => void
>a : number
>b : boolean
>c : string
f1((...x) => {})
>f1((...x) => {}) : void
>f1 : (cb: (args_0: number, args_1: boolean, args_2: string) => void) => void
>(...x) => {} : (args_0: number, args_1: boolean, args_2: string) => void
>x : [number, boolean, string]
f1((a, ...x) => {})
>f1((a, ...x) => {}) : void
>f1 : (cb: (args_0: number, args_1: boolean, args_2: string) => void) => void
>(a, ...x) => {} : (a: number, args_1: boolean, args_2: string) => void
>a : number
>x : [boolean, string]
f1((a, b, ...x) => {})
>f1((a, b, ...x) => {}) : void
>f1 : (cb: (args_0: number, args_1: boolean, args_2: string) => void) => void
>(a, b, ...x) => {} : (a: number, b: boolean, args_2: string) => void
>a : number
>b : boolean
>x : [string]
f1((a, b, c, ...x) => {})
>f1((a, b, c, ...x) => {}) : void
>f1 : (cb: (args_0: number, args_1: boolean, args_2: string) => void) => void
>(a, b, c, ...x) => {} : (a: number, b: boolean, c: string) => void
>a : number
>b : boolean
>c : string
>x : []
declare const t2: [number, boolean, ...string[]];
>t2 : [number, boolean, ...string[]]
(function (a, b, c){})(...t2);
>(function (a, b, c){})(...t2) : void
>(function (a, b, c){}) : (a: number, b?: boolean, c?: string) => void
>function (a, b, c){} : (a: number, b?: boolean, c?: string) => void
>a : number
>b : boolean
>c : string
>...t2 : string | number | boolean
>t2 : [number, boolean, ...string[]]
(function (...x){})(...t2);
>(function (...x){})(...t2) : void
>(function (...x){}) : (x_0: number, x_1: boolean, ...x_2: string[]) => void
>function (...x){} : (x_0: number, x_1: boolean, ...x_2: string[]) => void
>x : [number, boolean, ...string[]]
>...t2 : string | number | boolean
>t2 : [number, boolean, ...string[]]
(function (a, ...x){})(...t2);
>(function (a, ...x){})(...t2) : void
>(function (a, ...x){}) : (a: number, x_0: boolean, ...x_1: string[]) => void
>function (a, ...x){} : (a: number, x_0: boolean, ...x_1: string[]) => void
>a : number
>x : [boolean, ...string[]]
>...t2 : string | number | boolean
>t2 : [number, boolean, ...string[]]
(function (a, b, ...x){})(...t2);
>(function (a, b, ...x){})(...t2) : void
>(function (a, b, ...x){}) : (a: number, b?: boolean, ...x: string[]) => void
>function (a, b, ...x){} : (a: number, b?: boolean, ...x: string[]) => void
>a : number
>b : boolean
>x : string[]
>...t2 : string | number | boolean
>t2 : [number, boolean, ...string[]]
(function (a, b, c, ...x){})(...t2);
>(function (a, b, c, ...x){})(...t2) : void
>(function (a, b, c, ...x){}) : (a: number, b?: boolean, c?: string, ...x: string[]) => void
>function (a, b, c, ...x){} : (a: number, b?: boolean, c?: string, ...x: string[]) => void
>a : number
>b : boolean
>c : string
>x : string[]
>...t2 : string | number | boolean
>t2 : [number, boolean, ...string[]]
declare function f2(cb: (...args: typeof t2) => void): void;
>f2 : (cb: (args_0: number, args_1: boolean, ...args_2: string[]) => void) => void
>cb : (args_0: number, args_1: boolean, ...args_2: string[]) => void
>args : [number, boolean, ...string[]]
>t2 : [number, boolean, ...string[]]
f2((a, b, c) => {})
>f2((a, b, c) => {}) : void
>f2 : (cb: (args_0: number, args_1: boolean, ...args_2: string[]) => void) => void
>(a, b, c) => {} : (a: number, b: boolean, c: string) => void
>a : number
>b : boolean
>c : string
f2((...x) => {})
>f2((...x) => {}) : void
>f2 : (cb: (args_0: number, args_1: boolean, ...args_2: string[]) => void) => void
>(...x) => {} : (args_0: number, args_1: boolean, ...args_2: string[]) => void
>x : [number, boolean, ...string[]]
f2((a, ...x) => {})
>f2((a, ...x) => {}) : void
>f2 : (cb: (args_0: number, args_1: boolean, ...args_2: string[]) => void) => void
>(a, ...x) => {} : (a: number, args_1: boolean, ...args_2: string[]) => void
>a : number
>x : [boolean, ...string[]]
f2((a, b, ...x) => {})
>f2((a, b, ...x) => {}) : void
>f2 : (cb: (args_0: number, args_1: boolean, ...args_2: string[]) => void) => void
>(a, b, ...x) => {} : (a: number, b: boolean, ...x: string[]) => void
>a : number
>b : boolean
>x : string[]
f2((a, b, c, ...x) => {})
>f2((a, b, c, ...x) => {}) : void
>f2 : (cb: (args_0: number, args_1: boolean, ...args_2: string[]) => void) => void
>(a, b, c, ...x) => {} : (a: number, b: boolean, c: string, ...x: string[]) => void
>a : number
>b : boolean
>c : string
>x : string[]
declare const t3: [boolean, ...string[]];
>t3 : [boolean, ...string[]]
(function (a, b, c){})(1, ...t3);
>(function (a, b, c){})(1, ...t3) : void
>(function (a, b, c){}) : (a: number, b: boolean, c?: string) => void
>function (a, b, c){} : (a: number, b: boolean, c?: string) => void
>a : number
>b : boolean
>c : string
>1 : 1
>...t3 : string | boolean
>t3 : [boolean, ...string[]]
(function (...x){})(1, ...t3);
>(function (...x){})(1, ...t3) : void
>(function (...x){}) : (x_0: number, x_1: boolean, ...x_2: string[]) => void
>function (...x){} : (x_0: number, x_1: boolean, ...x_2: string[]) => void
>x : [number, boolean, ...string[]]
>1 : 1
>...t3 : string | boolean
>t3 : [boolean, ...string[]]
(function (a, ...x){})(1, ...t3);
>(function (a, ...x){})(1, ...t3) : void
>(function (a, ...x){}) : (a: number, x_0: boolean, ...x_1: string[]) => void
>function (a, ...x){} : (a: number, x_0: boolean, ...x_1: string[]) => void
>a : number
>x : [boolean, ...string[]]
>1 : 1
>...t3 : string | boolean
>t3 : [boolean, ...string[]]
(function (a, b, ...x){})(1, ...t3);
>(function (a, b, ...x){})(1, ...t3) : void
>(function (a, b, ...x){}) : (a: number, b: boolean, ...x: string[]) => void
>function (a, b, ...x){} : (a: number, b: boolean, ...x: string[]) => void
>a : number
>b : boolean
>x : string[]
>1 : 1
>...t3 : string | boolean
>t3 : [boolean, ...string[]]
(function (a, b, c, ...x){})(1, ...t3);
>(function (a, b, c, ...x){})(1, ...t3) : void
>(function (a, b, c, ...x){}) : (a: number, b: boolean, c?: string, ...x: string[]) => void
>function (a, b, c, ...x){} : (a: number, b: boolean, c?: string, ...x: string[]) => void
>a : number
>b : boolean
>c : string
>x : string[]
>1 : 1
>...t3 : string | boolean
>t3 : [boolean, ...string[]]
declare function f3(cb: (x: number, ...args: typeof t3) => void): void;
>f3 : (cb: (x: number, args_0: boolean, ...args_1: string[]) => void) => void
>cb : (x: number, args_0: boolean, ...args_1: string[]) => void
>x : number
>args : [boolean, ...string[]]
>t3 : [boolean, ...string[]]
f3((a, b, c) => {})
>f3((a, b, c) => {}) : void
>f3 : (cb: (x: number, args_0: boolean, ...args_1: string[]) => void) => void
>(a, b, c) => {} : (a: number, b: boolean, c: string) => void
>a : number
>b : boolean
>c : string
f3((...x) => {})
>f3((...x) => {}) : void
>f3 : (cb: (x: number, args_0: boolean, ...args_1: string[]) => void) => void
>(...x) => {} : (x: number, args_0: boolean, ...args_1: string[]) => void
>x : [number, boolean, ...string[]]
f3((a, ...x) => {})
>f3((a, ...x) => {}) : void
>f3 : (cb: (x: number, args_0: boolean, ...args_1: string[]) => void) => void
>(a, ...x) => {} : (a: number, args_0: boolean, ...args_1: string[]) => void
>a : number
>x : [boolean, ...string[]]
f3((a, b, ...x) => {})
>f3((a, b, ...x) => {}) : void
>f3 : (cb: (x: number, args_0: boolean, ...args_1: string[]) => void) => void
>(a, b, ...x) => {} : (a: number, b: boolean, ...x: string[]) => void
>a : number
>b : boolean
>x : string[]
f3((a, b, c, ...x) => {})
>f3((a, b, c, ...x) => {}) : void
>f3 : (cb: (x: number, args_0: boolean, ...args_1: string[]) => void) => void
>(a, b, c, ...x) => {} : (a: number, b: boolean, c: string, ...x: string[]) => void
>a : number
>b : boolean
>c : string
>x : string[]
function f4<T extends any[]>(t: T) {
>f4 : <T extends any[]>(t: T) => void
>T : T
>t : T
>T : T
(function(...x){})(...t);
>(function(...x){})(...t) : void
>(function(...x){}) : (...x: T) => void
>function(...x){} : (...x: T) => void
>x : T
>...t : any
>t : T
(function(a, ...x){})(1, ...t);
>(function(a, ...x){})(1, ...t) : void
>(function(a, ...x){}) : (a: number, ...x: T) => void
>function(a, ...x){} : (a: number, ...x: T) => void
>a : number
>x : T
>1 : 1
>...t : any
>t : T
(function(a, ...x){})(1, 2, ...t);
>(function(a, ...x){})(1, 2, ...t) : void
>(function(a, ...x){}) : (a: number, x_0: number, ...x_1: any[]) => void
>function(a, ...x){} : (a: number, x_0: number, ...x_1: any[]) => void
>a : number
>x : [number, ...any[]]
>1 : 1
>2 : 2
>...t : any
>t : T
function f(cb: (x: number, ...args: T) => void) {}
>f : (cb: (x: number, ...args: T) => void) => void
>cb : (x: number, ...args: T) => void
>x : number
>args : T
>T : T
f((...x) => {});
>f((...x) => {}) : void
>f : (cb: (x: number, ...args: T) => void) => void
>(...x) => {} : (x: number, ...args: any[]) => void
>x : [number, ...any[]]
f((a, ...x) => {});
>f((a, ...x) => {}) : void
>f : (cb: (x: number, ...args: T) => void) => void
>(a, ...x) => {} : (a: number, ...x: T) => void
>a : number
>x : T
f((a, b, ...x) => {});
>f((a, b, ...x) => {}) : void
>f : (cb: (x: number, ...args: T) => void) => void
>(a, b, ...x) => {} : (a: number, b: any, ...x: any[]) => void
>a : number
>b : any
>x : any[]
}
// Repro from #25288
declare var tuple: [number, string];
>tuple : [number, string]
(function foo(a, b){}(...tuple));
>(function foo(a, b){}(...tuple)) : void
>function foo(a, b){}(...tuple) : void
>function foo(a, b){} : (a: number, b?: string) => void
>foo : (a: number, b?: string) => void
>a : number
>b : string
>...tuple : string | number
>tuple : [number, string]
// Repro from #25289
declare function take(cb: (a: number, b: string) => void): void;
>take : (cb: (a: number, b: string) => void) => void
>cb : (a: number, b: string) => void
>a : number
>b : string
(function foo(...rest){}(1, ''));
>(function foo(...rest){}(1, '')) : void
>function foo(...rest){}(1, '') : void
>function foo(...rest){} : (rest_0: number, rest_1: string) => void
>foo : (rest_0: number, rest_1: string) => void
>rest : [number, string]
>1 : 1
>'' : ""
take(function(...rest){});
>take(function(...rest){}) : void
>take : (cb: (a: number, b: string) => void) => void
>function(...rest){} : (a: number, b: string) => void
>rest : [number, string]

View File

@ -0,0 +1,72 @@
// @strict: true
// @declaration: true
declare const t1: [number, boolean, string];
(function (a, b, c){})(...t1);
(function (...x){})(...t1);
(function (a, ...x){})(...t1);
(function (a, b, ...x){})(...t1);
(function (a, b, c, ...x){})(...t1);
declare function f1(cb: (...args: typeof t1) => void): void;
f1((a, b, c) => {})
f1((...x) => {})
f1((a, ...x) => {})
f1((a, b, ...x) => {})
f1((a, b, c, ...x) => {})
declare const t2: [number, boolean, ...string[]];
(function (a, b, c){})(...t2);
(function (...x){})(...t2);
(function (a, ...x){})(...t2);
(function (a, b, ...x){})(...t2);
(function (a, b, c, ...x){})(...t2);
declare function f2(cb: (...args: typeof t2) => void): void;
f2((a, b, c) => {})
f2((...x) => {})
f2((a, ...x) => {})
f2((a, b, ...x) => {})
f2((a, b, c, ...x) => {})
declare const t3: [boolean, ...string[]];
(function (a, b, c){})(1, ...t3);
(function (...x){})(1, ...t3);
(function (a, ...x){})(1, ...t3);
(function (a, b, ...x){})(1, ...t3);
(function (a, b, c, ...x){})(1, ...t3);
declare function f3(cb: (x: number, ...args: typeof t3) => void): void;
f3((a, b, c) => {})
f3((...x) => {})
f3((a, ...x) => {})
f3((a, b, ...x) => {})
f3((a, b, c, ...x) => {})
function f4<T extends any[]>(t: T) {
(function(...x){})(...t);
(function(a, ...x){})(1, ...t);
(function(a, ...x){})(1, 2, ...t);
function f(cb: (x: number, ...args: T) => void) {}
f((...x) => {});
f((a, ...x) => {});
f((a, b, ...x) => {});
}
// Repro from #25288
declare var tuple: [number, string];
(function foo(a, b){}(...tuple));
// Repro from #25289
declare function take(cb: (a: number, b: string) => void): void;
(function foo(...rest){}(1, ''));
take(function(...rest){});

View File

@ -38,12 +38,12 @@ verify.quickInfos({
4: "(parameter) y1: string[]",
5: "(parameter) y2: string",
t1: "(parameter) f1: any[]",
t1: "(parameter) f1: [string, string]",
t2: "(parameter) f1: any[]",
t2: "(parameter) f1: [string, ...string[]]",
t31: "(parameter) f1: number",
t32: "(parameter) f2: any[]",
t32: "(parameter) f2: [boolean, ...string[]]",
t4: "(parameter) f1: string[]",
t5: "(parameter) f1: string",