From c172314ba240ff577f5a9c862822b763c2866b87 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 2 Jul 2018 10:38:30 -1000 Subject: [PATCH 1/5] Infer contextual tuple types --- src/compiler/checker.ts | 76 ++++++++++++++++++++--------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index ef786831710..ce3dfa28d20 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -12386,22 +12386,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); } } @@ -15203,43 +15188,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); } } } @@ -17806,7 +17783,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 && (arg).isSpread); } @@ -18028,12 +18005,14 @@ namespace ts { } function getSpreadArgumentType(node: CallLikeExpression, args: ReadonlyArray, 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((arg).expression, restType, context); + return arg.kind === SyntaxKind.SyntheticExpression ? + createArrayType((arg).type) : + checkExpressionWithContextualType((arg).expression, restType, context); } } const contextualType = getIndexTypeOfType(restType, IndexKind.Number) || anyType; @@ -19560,6 +19539,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]); @@ -19653,11 +19653,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(parameter.valueDeclaration)) { - const contextualParameterType = getTypeOfSymbol(last(context.parameters)); + const contextualParameterType = getRestTypeAtPosition(context, len); assignTypeToParameterAndFixTypeParameters(parameter, contextualParameterType); } } From bf99b8e6c1b2b5a0076731f591de1bb200531c80 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 2 Jul 2018 10:38:54 -1000 Subject: [PATCH 2/5] Accept new baselines --- .../reference/contextuallyTypedIife.types | 42 +++++++++---------- .../contextuallyTypedIifeStrict.types | 42 +++++++++---------- ...tDefaultParametersFunctionExpression.types | 12 +++--- ...faultParametersFunctionExpressionES6.types | 12 +++--- ...emitRestParametersFunctionExpression.types | 6 +-- ...tRestParametersFunctionExpressionES6.types | 6 +-- ...edFunctionInferenceWithTypeParameter.types | 6 +-- 7 files changed, 63 insertions(+), 63 deletions(-) diff --git a/tests/baselines/reference/contextuallyTypedIife.types b/tests/baselines/reference/contextuallyTypedIife.types index 7b86fe1f337..df0b7884594 100644 --- a/tests/baselines/reference/contextuallyTypedIife.types +++ b/tests/baselines/reference/contextuallyTypedIife.types @@ -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 : (callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[] ->rest : number[] +>rest : [number, number] >map : (callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[] >n => n > 0 : (n: number) => boolean >n : number diff --git a/tests/baselines/reference/contextuallyTypedIifeStrict.types b/tests/baselines/reference/contextuallyTypedIifeStrict.types index 5a8a33ac41d..e20c08a20de 100644 --- a/tests/baselines/reference/contextuallyTypedIifeStrict.types +++ b/tests/baselines/reference/contextuallyTypedIifeStrict.types @@ -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 : (callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[] ->rest : number[] +>rest : [number, number] >map : (callbackfn: (value: number, index: number, array: number[]) => U, thisArg?: any) => U[] >n => n > 0 : (n: number) => boolean >n : number diff --git a/tests/baselines/reference/emitDefaultParametersFunctionExpression.types b/tests/baselines/reference/emitDefaultParametersFunctionExpression.types index 7546bda0d41..e8707ba653e 100644 --- a/tests/baselines/reference/emitDefaultParametersFunctionExpression.types +++ b/tests/baselines/reference/emitDefaultParametersFunctionExpression.types @@ -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 diff --git a/tests/baselines/reference/emitDefaultParametersFunctionExpressionES6.types b/tests/baselines/reference/emitDefaultParametersFunctionExpressionES6.types index 99ab6a48137..adf70cde16f 100644 --- a/tests/baselines/reference/emitDefaultParametersFunctionExpressionES6.types +++ b/tests/baselines/reference/emitDefaultParametersFunctionExpressionES6.types @@ -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 diff --git a/tests/baselines/reference/emitRestParametersFunctionExpression.types b/tests/baselines/reference/emitRestParametersFunctionExpression.types index 9f08b9d9d83..bb3e1c8028b 100644 --- a/tests/baselines/reference/emitRestParametersFunctionExpression.types +++ b/tests/baselines/reference/emitRestParametersFunctionExpression.types @@ -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 : [] diff --git a/tests/baselines/reference/emitRestParametersFunctionExpressionES6.types b/tests/baselines/reference/emitRestParametersFunctionExpressionES6.types index 224cb37367a..c06b359b89c 100644 --- a/tests/baselines/reference/emitRestParametersFunctionExpressionES6.types +++ b/tests/baselines/reference/emitRestParametersFunctionExpressionES6.types @@ -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 : [] diff --git a/tests/baselines/reference/partiallyAnnotatedFunctionInferenceWithTypeParameter.types b/tests/baselines/reference/partiallyAnnotatedFunctionInferenceWithTypeParameter.types index c2113ae4d75..96e4c8b1c31 100644 --- a/tests/baselines/reference/partiallyAnnotatedFunctionInferenceWithTypeParameter.types +++ b/tests/baselines/reference/partiallyAnnotatedFunctionInferenceWithTypeParameter.types @@ -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 : (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 From e5d520e463137ff9291b4baf1a80456252bf3336 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 2 Jul 2018 17:50:42 -1000 Subject: [PATCH 3/5] Add tests --- .../rest/restTuplesFromContextualTypes.ts | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 tests/cases/conformance/types/rest/restTuplesFromContextualTypes.ts diff --git a/tests/cases/conformance/types/rest/restTuplesFromContextualTypes.ts b/tests/cases/conformance/types/rest/restTuplesFromContextualTypes.ts new file mode 100644 index 00000000000..84bf81195b0 --- /dev/null +++ b/tests/cases/conformance/types/rest/restTuplesFromContextualTypes.ts @@ -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: 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){}); From 38a0346899e6206788ff47adb9d9b51064ce0645 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 2 Jul 2018 17:50:52 -1000 Subject: [PATCH 4/5] Accept new baselines --- .../restTuplesFromContextualTypes.js | 288 +++++++++++++ .../restTuplesFromContextualTypes.symbols | 267 ++++++++++++ .../restTuplesFromContextualTypes.types | 394 ++++++++++++++++++ 3 files changed, 949 insertions(+) create mode 100644 tests/baselines/reference/restTuplesFromContextualTypes.js create mode 100644 tests/baselines/reference/restTuplesFromContextualTypes.symbols create mode 100644 tests/baselines/reference/restTuplesFromContextualTypes.types diff --git a/tests/baselines/reference/restTuplesFromContextualTypes.js b/tests/baselines/reference/restTuplesFromContextualTypes.js new file mode 100644 index 00000000000..3db6c53f384 --- /dev/null +++ b/tests/baselines/reference/restTuplesFromContextualTypes.js @@ -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: 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: T): void; +declare var tuple: [number, string]; +declare function take(cb: (a: number, b: string) => void): void; diff --git a/tests/baselines/reference/restTuplesFromContextualTypes.symbols b/tests/baselines/reference/restTuplesFromContextualTypes.symbols new file mode 100644 index 00000000000..d9b2310b5e2 --- /dev/null +++ b/tests/baselines/reference/restTuplesFromContextualTypes.symbols @@ -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: 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)) + diff --git a/tests/baselines/reference/restTuplesFromContextualTypes.types b/tests/baselines/reference/restTuplesFromContextualTypes.types new file mode 100644 index 00000000000..49824b2fb6a --- /dev/null +++ b/tests/baselines/reference/restTuplesFromContextualTypes.types @@ -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: T) { +>f4 : (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] + From 17e959407c1dd2f158dbf65e6eae4e6fbaadf9bb Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 2 Jul 2018 18:14:32 -1000 Subject: [PATCH 5/5] Fix fourslash tests --- tests/cases/fourslash/restArgType.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/cases/fourslash/restArgType.ts b/tests/cases/fourslash/restArgType.ts index 01c285207f8..69601c14ccf 100644 --- a/tests/cases/fourslash/restArgType.ts +++ b/tests/cases/fourslash/restArgType.ts @@ -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",