From b4b711ff5c7e5f07db43c139309b4e34fdcda853 Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 23 Oct 2017 12:35:11 -0700 Subject: [PATCH 1/7] Infer from base constraint signatures instead of erased signatures --- src/compiler/checker.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index da3dac4d605..6938ed8d77f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -6726,6 +6726,16 @@ namespace ts { isInJavaScriptFile(signature.declaration)); } + function getBaseSignature(signature: Signature) { + const typeParameters = signature.typeParameters; + if (typeParameters) { + const typeEraser = createTypeEraser(typeParameters); + const baseConstraints = map(typeParameters, tp => instantiateType(getBaseConstraintOfType(tp), typeEraser) || emptyObjectType); + return instantiateSignature(signature, createTypeMapper(typeParameters, baseConstraints), /*eraseTypeParameters*/ true); + } + return signature; + } + function getOrCreateTypeFromSignature(signature: Signature): ObjectType { // There are two ways to declare a construct signature, one is by declaring a class constructor // using the constructor keyword, and the other is declaring a bare construct signature in an @@ -10955,7 +10965,7 @@ namespace ts { const targetLen = targetSignatures.length; const len = sourceLen < targetLen ? sourceLen : targetLen; for (let i = 0; i < len; i++) { - inferFromSignature(getErasedSignature(sourceSignatures[sourceLen - len + i]), getErasedSignature(targetSignatures[targetLen - len + i])); + inferFromSignature(getBaseSignature(sourceSignatures[sourceLen - len + i]), getBaseSignature(targetSignatures[targetLen - len + i])); } } From a87baa2664fa51fd4e8e29c47599aece5ccd45ff Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 23 Oct 2017 12:36:29 -0700 Subject: [PATCH 2/7] Accept new baselines --- ...lWithConstructorTypedArguments5.errors.txt | 8 +++---- ...nericCallWithFunctionTypedArguments2.types | 24 +++++++++---------- ...hOverloadedConstructorTypedArguments.types | 20 ++++++++-------- ...oadedConstructorTypedArguments2.errors.txt | 4 ++-- ...OverloadedConstructorTypedArguments2.types | 12 +++++----- ...WithOverloadedFunctionTypedArguments.types | 20 ++++++++-------- ...erloadedFunctionTypedArguments2.errors.txt | 4 ++-- ...ithOverloadedFunctionTypedArguments2.types | 12 +++++----- .../reference/promisePermutations.types | 16 ++++++------- .../reference/promisePermutations2.types | 16 ++++++------- .../reference/promisePermutations3.errors.txt | 8 +++---- .../reference/promisePermutations3.types | 12 +++++----- 12 files changed, 78 insertions(+), 78 deletions(-) diff --git a/tests/baselines/reference/genericCallWithConstructorTypedArguments5.errors.txt b/tests/baselines/reference/genericCallWithConstructorTypedArguments5.errors.txt index a014ef85b6c..4aa29b1e050 100644 --- a/tests/baselines/reference/genericCallWithConstructorTypedArguments5.errors.txt +++ b/tests/baselines/reference/genericCallWithConstructorTypedArguments5.errors.txt @@ -1,6 +1,6 @@ -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithConstructorTypedArguments5.ts(11,14): error TS2345: Argument of type '{ cb: new (x: T, y: T) => string; }' is not assignable to parameter of type '{ cb: new (t: any) => string; }'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithConstructorTypedArguments5.ts(11,14): error TS2345: Argument of type '{ cb: new (x: T, y: T) => string; }' is not assignable to parameter of type '{ cb: new (t: {}) => string; }'. Types of property 'cb' are incompatible. - Type 'new (x: T, y: T) => string' is not assignable to type 'new (t: any) => string'. + Type 'new (x: T, y: T) => string' is not assignable to type 'new (t: {}) => string'. tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithConstructorTypedArguments5.ts(13,14): error TS2345: Argument of type '{ cb: new (x: string, y: number) => string; }' is not assignable to parameter of type '{ cb: new (t: string) => string; }'. Types of property 'cb' are incompatible. Type 'new (x: string, y: number) => string' is not assignable to type 'new (t: string) => string'. @@ -19,9 +19,9 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithCon var arg2: { cb: new (x: T, y: T) => string }; var r2 = foo(arg2); // error ~~~~ -!!! error TS2345: Argument of type '{ cb: new (x: T, y: T) => string; }' is not assignable to parameter of type '{ cb: new (t: any) => string; }'. +!!! error TS2345: Argument of type '{ cb: new (x: T, y: T) => string; }' is not assignable to parameter of type '{ cb: new (t: {}) => string; }'. !!! error TS2345: Types of property 'cb' are incompatible. -!!! error TS2345: Type 'new (x: T, y: T) => string' is not assignable to type 'new (t: any) => string'. +!!! error TS2345: Type 'new (x: T, y: T) => string' is not assignable to type 'new (t: {}) => string'. var arg3: { cb: new (x: string, y: number) => string }; var r3 = foo(arg3); // error ~~~~ diff --git a/tests/baselines/reference/genericCallWithFunctionTypedArguments2.types b/tests/baselines/reference/genericCallWithFunctionTypedArguments2.types index 16bc5ae774a..967850180d6 100644 --- a/tests/baselines/reference/genericCallWithFunctionTypedArguments2.types +++ b/tests/baselines/reference/genericCallWithFunctionTypedArguments2.types @@ -53,8 +53,8 @@ var a: { } var r = foo(i); // any ->r : any ->foo(i) : any +>r : {} +>foo(i) : {} >foo : (x: new (a: T) => T) => T >i : I @@ -71,8 +71,8 @@ var r3 = foo(i2); // string >i2 : I2 var r3b = foo(a); // any ->r3b : any ->foo(a) : any +>r3b : {} +>foo(a) : {} >foo : (x: new (a: T) => T) => T >a : new (x: T) => T @@ -101,15 +101,15 @@ var r4 = foo2(1, i2); // error >i2 : I2 var r4b = foo2(1, a); // any ->r4b : any ->foo2(1, a) : any +>r4b : {} +>foo2(1, a) : {} >foo2 : (x: T, cb: new (a: T) => U) => U >1 : 1 >a : new (x: T) => T var r5 = foo2(1, i); // any ->r5 : any ->foo2(1, i) : any +>r5 : {} +>foo2(1, i) : {} >foo2 : (x: T, cb: new (a: T) => U) => U >1 : 1 >i : I @@ -141,16 +141,16 @@ function foo3(x: T, cb: new(a: T) => U, y: U) { } var r7 = foo3(null, i, ''); // any ->r7 : any ->foo3(null, i, '') : any +>r7 : {} +>foo3(null, i, '') : {} >foo3 : (x: T, cb: new (a: T) => U, y: U) => U >null : null >i : I >'' : "" var r7b = foo3(null, a, ''); // any ->r7b : any ->foo3(null, a, '') : any +>r7b : {} +>foo3(null, a, '') : {} >foo3 : (x: T, cb: new (a: T) => U, y: U) => U >null : null >a : new (x: T) => T diff --git a/tests/baselines/reference/genericCallWithOverloadedConstructorTypedArguments.types b/tests/baselines/reference/genericCallWithOverloadedConstructorTypedArguments.types index 15e746f615a..682910656ff 100644 --- a/tests/baselines/reference/genericCallWithOverloadedConstructorTypedArguments.types +++ b/tests/baselines/reference/genericCallWithOverloadedConstructorTypedArguments.types @@ -87,8 +87,8 @@ module GenericParameter { >T : T var r7 = foo5(b); // new any => string; new(x:number) => any ->r7 : { new (x: any): string; new (x: number): any; } ->foo5(b) : { new (x: any): string; new (x: number): any; } +>r7 : { new (x: {}): string; new (x: number): {}; } +>foo5(b) : { new (x: {}): string; new (x: number): {}; } >foo5 : (cb: { new (x: T): string; new (x: number): T; }) => { new (x: T): string; new (x: number): T; } >b : { new (x: T): string; new (x: number): T; } @@ -114,8 +114,8 @@ module GenericParameter { >a : { new (x: boolean): string; new (x: number): boolean; } var r9 = foo6(b); // new any => string; new(x:any, y?:any) => string ->r9 : { new (x: any): string; new (x: any, y?: any): string; } ->foo6(b) : { new (x: any): string; new (x: any, y?: any): string; } +>r9 : { new (x: {}): string; new (x: {}, y?: {}): string; } +>foo6(b) : { new (x: {}): string; new (x: {}, y?: {}): string; } >foo6 : (cb: { new (x: T): string; new (x: T, y?: T): string; }) => { new (x: T): string; new (x: T, y?: T): string; } >b : { new (x: T): string; new (x: number): T; } @@ -137,8 +137,8 @@ module GenericParameter { } var r13 = foo7(1, b); // new any => string; new(x:any, y?:any) => string ->r13 : { new (x: any): string; new (x: any, y?: any): string; } ->foo7(1, b) : { new (x: any): string; new (x: any, y?: any): string; } +>r13 : { new (x: {}): string; new (x: {}, y?: {}): string; } +>foo7(1, b) : { new (x: {}): string; new (x: {}, y?: {}): string; } >foo7 : (x: T, cb: { new (x: T): string; new (x: T, y?: T): string; }) => { new (x: T): string; new (x: T, y?: T): string; } >1 : 1 >b : { new (x: T): string; new (x: number): T; } @@ -162,15 +162,15 @@ module GenericParameter { >T : T var r14 = foo7(1, c); // new any => string; new(x:any, y?:any) => string ->r14 : { new (x: any): string; new (x: any, y?: any): string; } ->foo7(1, c) : { new (x: any): string; new (x: any, y?: any): string; } +>r14 : { new (x: {}): string; new (x: {}, y?: {}): string; } +>foo7(1, c) : { new (x: {}): string; new (x: {}, y?: {}): string; } >foo7 : (x: T, cb: { new (x: T): string; new (x: T, y?: T): string; }) => { new (x: T): string; new (x: T, y?: T): string; } >1 : 1 >c : { (x: number): T; new (x: T): string; } var r15 = foo7(1, c2); // new any => string; new(x:any, y?:any) => string ->r15 : { new (x: any): string; new (x: any, y?: any): string; } ->foo7(1, c2) : { new (x: any): string; new (x: any, y?: any): string; } +>r15 : { new (x: {}): string; new (x: {}, y?: {}): string; } +>foo7(1, c2) : { new (x: {}): string; new (x: {}, y?: {}): string; } >foo7 : (x: T, cb: { new (x: T): string; new (x: T, y?: T): string; }) => { new (x: T): string; new (x: T, y?: T): string; } >1 : 1 >c2 : { new (x: T): string; new (x: number): T; } diff --git a/tests/baselines/reference/genericCallWithOverloadedConstructorTypedArguments2.errors.txt b/tests/baselines/reference/genericCallWithOverloadedConstructorTypedArguments2.errors.txt index 80bcf12494a..cb40b4acb7a 100644 --- a/tests/baselines/reference/genericCallWithOverloadedConstructorTypedArguments2.errors.txt +++ b/tests/baselines/reference/genericCallWithOverloadedConstructorTypedArguments2.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithOverloadedConstructorTypedArguments2.ts(31,20): error TS2345: Argument of type 'new (x: T, y: T) => string' is not assignable to parameter of type '{ new (x: any): string; new (x: any, y?: any): string; }'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithOverloadedConstructorTypedArguments2.ts(31,20): error TS2345: Argument of type 'new (x: T, y: T) => string' is not assignable to parameter of type '{ new (x: {}): string; new (x: {}, y?: {}): string; }'. ==== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithOverloadedConstructorTypedArguments2.ts (1 errors) ==== @@ -34,7 +34,7 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithOve var b: { new (x: T, y: T): string }; var r10 = foo6(b); // error ~ -!!! error TS2345: Argument of type 'new (x: T, y: T) => string' is not assignable to parameter of type '{ new (x: any): string; new (x: any, y?: any): string; }'. +!!! error TS2345: Argument of type 'new (x: T, y: T) => string' is not assignable to parameter of type '{ new (x: {}): string; new (x: {}, y?: {}): string; }'. function foo7(x:T, cb: { new(x: T): string; new(x: T, y?: T): string }) { return cb; diff --git a/tests/baselines/reference/genericCallWithOverloadedConstructorTypedArguments2.types b/tests/baselines/reference/genericCallWithOverloadedConstructorTypedArguments2.types index e9b65c6f1da..557c63914fe 100644 --- a/tests/baselines/reference/genericCallWithOverloadedConstructorTypedArguments2.types +++ b/tests/baselines/reference/genericCallWithOverloadedConstructorTypedArguments2.types @@ -63,8 +63,8 @@ module GenericParameter { >T : T var r6 = foo5(a); // ok ->r6 : { new (x: any): string; new (x: number): any; } ->foo5(a) : { new (x: any): string; new (x: number): any; } +>r6 : { new (x: {}): string; new (x: number): {}; } +>foo5(a) : { new (x: {}): string; new (x: number): {}; } >foo5 : (cb: { new (x: T): string; new (x: number): T; }) => { new (x: T): string; new (x: number): T; } >a : new (x: T) => T @@ -115,8 +115,8 @@ module GenericParameter { } var r13 = foo7(1, a); // ok ->r13 : { new (x: any): string; new (x: any, y?: any): string; } ->foo7(1, a) : { new (x: any): string; new (x: any, y?: any): string; } +>r13 : { new (x: {}): string; new (x: {}, y?: {}): string; } +>foo7(1, a) : { new (x: {}): string; new (x: {}, y?: {}): string; } >foo7 : (x: T, cb: { new (x: T): string; new (x: T, y?: T): string; }) => { new (x: T): string; new (x: T, y?: T): string; } >1 : 1 >a : new (x: T) => T @@ -131,8 +131,8 @@ module GenericParameter { >T : T var r14 = foo7(1, c); // ok ->r14 : { new (x: any): string; new (x: any, y?: any): string; } ->foo7(1, c) : { new (x: any): string; new (x: any, y?: any): string; } +>r14 : { new (x: {}): string; new (x: {}, y?: {}): string; } +>foo7(1, c) : { new (x: {}): string; new (x: {}, y?: {}): string; } >foo7 : (x: T, cb: { new (x: T): string; new (x: T, y?: T): string; }) => { new (x: T): string; new (x: T, y?: T): string; } >1 : 1 >c : { new (x: T): number; new (x: number): T; } diff --git a/tests/baselines/reference/genericCallWithOverloadedFunctionTypedArguments.types b/tests/baselines/reference/genericCallWithOverloadedFunctionTypedArguments.types index ab07e9c880a..55bec0c2a9f 100644 --- a/tests/baselines/reference/genericCallWithOverloadedFunctionTypedArguments.types +++ b/tests/baselines/reference/genericCallWithOverloadedFunctionTypedArguments.types @@ -83,8 +83,8 @@ module GenericParameter { >T : T var r7 = foo5(a); // any => string (+1 overload) ->r7 : { (x: any): string; (x: number): any; } ->foo5(a) : { (x: any): string; (x: number): any; } +>r7 : { (x: {}): string; (x: number): {}; } +>foo5(a) : { (x: {}): string; (x: number): {}; } >foo5 : (cb: { (x: T): string; (x: number): T; }) => { (x: T): string; (x: number): T; } >a : { (x: T): string; (x: number): T; } @@ -112,8 +112,8 @@ module GenericParameter { >x : any var r9 = foo6((x: T) => ''); // any => string (+1 overload) ->r9 : { (x: any): string; (x: any, y?: any): string; } ->foo6((x: T) => '') : { (x: any): string; (x: any, y?: any): string; } +>r9 : { (x: {}): string; (x: {}, y?: {}): string; } +>foo6((x: T) => '') : { (x: {}): string; (x: {}, y?: {}): string; } >foo6 : (cb: { (x: T): string; (x: T, y?: T): string; }) => { (x: T): string; (x: T, y?: T): string; } >(x: T) => '' : (x: T) => string >T : T @@ -122,8 +122,8 @@ module GenericParameter { >'' : "" var r11 = foo6((x: T, y?: T) => ''); // any => string (+1 overload) ->r11 : { (x: any): string; (x: any, y?: any): string; } ->foo6((x: T, y?: T) => '') : { (x: any): string; (x: any, y?: any): string; } +>r11 : { (x: {}): string; (x: {}, y?: {}): string; } +>foo6((x: T, y?: T) => '') : { (x: {}): string; (x: {}, y?: {}): string; } >foo6 : (cb: { (x: T): string; (x: T, y?: T): string; }) => { (x: T): string; (x: T, y?: T): string; } >(x: T, y?: T) => '' : (x: T, y?: T) => string >T : T @@ -160,8 +160,8 @@ module GenericParameter { >x : any var r13 = foo7(1, (x: T) => ''); // any => string (+1 overload) [inferences are made for T, but lambda not contextually typed] ->r13 : { (x: any): string; (x: any, y?: any): string; } ->foo7(1, (x: T) => '') : { (x: any): string; (x: any, y?: any): string; } +>r13 : { (x: {}): string; (x: {}, y?: {}): string; } +>foo7(1, (x: T) => '') : { (x: {}): string; (x: {}, y?: {}): string; } >foo7 : (x: T, cb: { (x: T): string; (x: T, y?: T): string; }) => { (x: T): string; (x: T, y?: T): string; } >1 : 1 >(x: T) => '' : (x: T) => string @@ -180,8 +180,8 @@ module GenericParameter { >T : T var r14 = foo7(1, a); // any => string (+1 overload) [inferences are made for T, but lambda not contextually typed] ->r14 : { (x: any): string; (x: any, y?: any): string; } ->foo7(1, a) : { (x: any): string; (x: any, y?: any): string; } +>r14 : { (x: {}): string; (x: {}, y?: {}): string; } +>foo7(1, a) : { (x: {}): string; (x: {}, y?: {}): string; } >foo7 : (x: T, cb: { (x: T): string; (x: T, y?: T): string; }) => { (x: T): string; (x: T, y?: T): string; } >1 : 1 >a : { (x: T): string; (x: number): T; } diff --git a/tests/baselines/reference/genericCallWithOverloadedFunctionTypedArguments2.errors.txt b/tests/baselines/reference/genericCallWithOverloadedFunctionTypedArguments2.errors.txt index 32fe6a09344..9ee5e6f0cfe 100644 --- a/tests/baselines/reference/genericCallWithOverloadedFunctionTypedArguments2.errors.txt +++ b/tests/baselines/reference/genericCallWithOverloadedFunctionTypedArguments2.errors.txt @@ -1,4 +1,4 @@ -tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithOverloadedFunctionTypedArguments2.ts(28,20): error TS2345: Argument of type '(x: T, y: T) => string' is not assignable to parameter of type '{ (x: any): string; (x: any, y?: any): string; }'. +tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithOverloadedFunctionTypedArguments2.ts(28,20): error TS2345: Argument of type '(x: T, y: T) => string' is not assignable to parameter of type '{ (x: {}): string; (x: {}, y?: {}): string; }'. ==== tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithOverloadedFunctionTypedArguments2.ts (1 errors) ==== @@ -31,7 +31,7 @@ tests/cases/conformance/types/typeRelationships/typeInference/genericCallWithOve var r10 = foo6((x: T, y: T) => ''); // error ~~~~~~~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '(x: T, y: T) => string' is not assignable to parameter of type '{ (x: any): string; (x: any, y?: any): string; }'. +!!! error TS2345: Argument of type '(x: T, y: T) => string' is not assignable to parameter of type '{ (x: {}): string; (x: {}, y?: {}): string; }'. function foo7(x:T, cb: { (x: T): string; (x: T, y?: T): string }) { return cb; diff --git a/tests/baselines/reference/genericCallWithOverloadedFunctionTypedArguments2.types b/tests/baselines/reference/genericCallWithOverloadedFunctionTypedArguments2.types index da52da85044..7bc9be99a59 100644 --- a/tests/baselines/reference/genericCallWithOverloadedFunctionTypedArguments2.types +++ b/tests/baselines/reference/genericCallWithOverloadedFunctionTypedArguments2.types @@ -55,8 +55,8 @@ module GenericParameter { } var r6 = foo5((x: T) => x); // ok ->r6 : { (x: any): string; (x: number): any; } ->foo5((x: T) => x) : { (x: any): string; (x: number): any; } +>r6 : { (x: {}): string; (x: number): {}; } +>foo5((x: T) => x) : { (x: {}): string; (x: number): {}; } >foo5 : (cb: { (x: T): string; (x: number): T; }) => { (x: T): string; (x: number): T; } >(x: T) => x : (x: T) => T >T : T @@ -109,8 +109,8 @@ module GenericParameter { } var r13 = foo7(1, (x: T) => x); // ok ->r13 : { (x: any): string; (x: any, y?: any): string; } ->foo7(1, (x: T) => x) : { (x: any): string; (x: any, y?: any): string; } +>r13 : { (x: {}): string; (x: {}, y?: {}): string; } +>foo7(1, (x: T) => x) : { (x: {}): string; (x: {}, y?: {}): string; } >foo7 : (x: T, cb: { (x: T): string; (x: T, y?: T): string; }) => { (x: T): string; (x: T, y?: T): string; } >1 : 1 >(x: T) => x : (x: T) => T @@ -129,8 +129,8 @@ module GenericParameter { >T : T var r14 = foo7(1, a); // ok ->r14 : { (x: any): string; (x: any, y?: any): string; } ->foo7(1, a) : { (x: any): string; (x: any, y?: any): string; } +>r14 : { (x: {}): string; (x: {}, y?: {}): string; } +>foo7(1, a) : { (x: {}): string; (x: {}, y?: {}): string; } >foo7 : (x: T, cb: { (x: T): string; (x: T, y?: T): string; }) => { (x: T): string; (x: T, y?: T): string; } >1 : 1 >a : { (x: T): number; (x: number): T; } diff --git a/tests/baselines/reference/promisePermutations.types b/tests/baselines/reference/promisePermutations.types index 1b8ec25b639..df057583cc2 100644 --- a/tests/baselines/reference/promisePermutations.types +++ b/tests/baselines/reference/promisePermutations.types @@ -1396,8 +1396,8 @@ var r12 = testFunction12(x => x); >x : any var r12a = r12.then(testFunction12, testFunction12, testFunction12); // ok ->r12a : IPromise ->r12.then(testFunction12, testFunction12, testFunction12) : IPromise +>r12a : IPromise<{}> +>r12.then(testFunction12, testFunction12, testFunction12) : IPromise<{}> >r12.then : { (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; } >r12 : IPromise<(x: any) => any> >then : { (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; } @@ -1414,8 +1414,8 @@ var s12 = testFunction12(x => x); >x : any var s12a = s12.then(testFunction12, testFunction12, testFunction12); // ok ->s12a : IPromise ->s12.then(testFunction12, testFunction12, testFunction12) : IPromise +>s12a : IPromise<{}> +>s12.then(testFunction12, testFunction12, testFunction12) : IPromise<{}> >s12.then : { (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; } >s12 : IPromise<(x: any) => any> >then : { (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; } @@ -1424,8 +1424,8 @@ var s12a = s12.then(testFunction12, testFunction12, testFunction12); // ok >testFunction12 : { (x: T): IPromise; (x: T, y: T): IPromise; } var s12b = s12.then(testFunction12P, testFunction12P, testFunction12P); // ok ->s12b : IPromise ->s12.then(testFunction12P, testFunction12P, testFunction12P) : IPromise +>s12b : IPromise<{}> +>s12.then(testFunction12P, testFunction12P, testFunction12P) : IPromise<{}> >s12.then : { (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; } >s12 : IPromise<(x: any) => any> >then : { (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; } @@ -1434,8 +1434,8 @@ var s12b = s12.then(testFunction12P, testFunction12P, testFunction12P); // ok >testFunction12P : { (x: T): IPromise; (x: T, y: T): Promise; } var s12c = s12.then(testFunction12P, testFunction12, testFunction12); // ok ->s12c : IPromise ->s12.then(testFunction12P, testFunction12, testFunction12) : IPromise +>s12c : IPromise<{}> +>s12.then(testFunction12P, testFunction12, testFunction12) : IPromise<{}> >s12.then : { (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; } >s12 : IPromise<(x: any) => any> >then : { (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; } diff --git a/tests/baselines/reference/promisePermutations2.types b/tests/baselines/reference/promisePermutations2.types index 0e3af43b86f..28a74aa7d77 100644 --- a/tests/baselines/reference/promisePermutations2.types +++ b/tests/baselines/reference/promisePermutations2.types @@ -1349,8 +1349,8 @@ var r12 = testFunction12(x => x); >x : any var r12a = r12.then(testFunction12, testFunction12, testFunction12); // ok ->r12a : IPromise ->r12.then(testFunction12, testFunction12, testFunction12) : IPromise +>r12a : IPromise<{}> +>r12.then(testFunction12, testFunction12, testFunction12) : IPromise<{}> >r12.then : { (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; } >r12 : IPromise<(x: any) => any> >then : { (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; } @@ -1367,8 +1367,8 @@ var s12 = testFunction12(x => x); >x : any var s12a = s12.then(testFunction12, testFunction12, testFunction12); // ok ->s12a : IPromise ->s12.then(testFunction12, testFunction12, testFunction12) : IPromise +>s12a : IPromise<{}> +>s12.then(testFunction12, testFunction12, testFunction12) : IPromise<{}> >s12.then : { (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; } >s12 : IPromise<(x: any) => any> >then : { (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; } @@ -1377,8 +1377,8 @@ var s12a = s12.then(testFunction12, testFunction12, testFunction12); // ok >testFunction12 : { (x: T): IPromise; (x: T, y: T): IPromise; } var s12b = s12.then(testFunction12P, testFunction12P, testFunction12P); // ok ->s12b : IPromise ->s12.then(testFunction12P, testFunction12P, testFunction12P) : IPromise +>s12b : IPromise<{}> +>s12.then(testFunction12P, testFunction12P, testFunction12P) : IPromise<{}> >s12.then : { (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; } >s12 : IPromise<(x: any) => any> >then : { (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; } @@ -1387,8 +1387,8 @@ var s12b = s12.then(testFunction12P, testFunction12P, testFunction12P); // ok >testFunction12P : { (x: T): IPromise; (x: T, y: T): Promise; } var s12c = s12.then(testFunction12P, testFunction12, testFunction12); // ok ->s12c : IPromise ->s12.then(testFunction12P, testFunction12, testFunction12) : IPromise +>s12c : IPromise<{}> +>s12.then(testFunction12P, testFunction12, testFunction12) : IPromise<{}> >s12.then : { (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; } >s12 : IPromise<(x: any) => any> >then : { (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => IPromise, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => IPromise, progress?: (progress: any) => void): IPromise; (success?: (value: (x: any) => any) => U, error?: (error: any) => U, progress?: (progress: any) => void): IPromise; } diff --git a/tests/baselines/reference/promisePermutations3.errors.txt b/tests/baselines/reference/promisePermutations3.errors.txt index 8e99b92d53a..e995c4f1d38 100644 --- a/tests/baselines/reference/promisePermutations3.errors.txt +++ b/tests/baselines/reference/promisePermutations3.errors.txt @@ -66,8 +66,8 @@ tests/cases/compiler/promisePermutations3.ts(159,21): error TS2345: Argument of Types of parameters 'onfulfilled' and 'success' are incompatible. Types of parameters 'value' and 'value' are incompatible. Type 'number' is not assignable to type 'string'. -tests/cases/compiler/promisePermutations3.ts(165,21): error TS2345: Argument of type '{ (x: T): IPromise; (x: T, y: T): Promise; }' is not assignable to parameter of type '(value: (x: any) => any) => Promise'. - Type 'IPromise' is not assignable to type 'Promise'. +tests/cases/compiler/promisePermutations3.ts(165,21): error TS2345: Argument of type '{ (x: T): IPromise; (x: T, y: T): Promise; }' is not assignable to parameter of type '(value: (x: any) => any) => Promise<{}>'. + Type 'IPromise' is not assignable to type 'Promise<{}>'. Property 'catch' is missing in type 'IPromise'. @@ -340,7 +340,7 @@ tests/cases/compiler/promisePermutations3.ts(165,21): error TS2345: Argument of var s12a = s12.then(testFunction12, testFunction12, testFunction12); // ok var s12b = s12.then(testFunction12P, testFunction12P, testFunction12P); // ok ~~~~~~~~~~~~~~~ -!!! error TS2345: Argument of type '{ (x: T): IPromise; (x: T, y: T): Promise; }' is not assignable to parameter of type '(value: (x: any) => any) => Promise'. -!!! error TS2345: Type 'IPromise' is not assignable to type 'Promise'. +!!! error TS2345: Argument of type '{ (x: T): IPromise; (x: T, y: T): Promise; }' is not assignable to parameter of type '(value: (x: any) => any) => Promise<{}>'. +!!! error TS2345: Type 'IPromise' is not assignable to type 'Promise<{}>'. !!! error TS2345: Property 'catch' is missing in type 'IPromise'. var s12c = s12.then(testFunction12P, testFunction12, testFunction12); // ok \ No newline at end of file diff --git a/tests/baselines/reference/promisePermutations3.types b/tests/baselines/reference/promisePermutations3.types index 34eff1806d6..ab6390ae77d 100644 --- a/tests/baselines/reference/promisePermutations3.types +++ b/tests/baselines/reference/promisePermutations3.types @@ -1349,8 +1349,8 @@ var r12 = testFunction12(x => x); >x : any var r12a = r12.then(testFunction12, testFunction12, testFunction12); // ok ->r12a : IPromise> ->r12.then(testFunction12, testFunction12, testFunction12) : IPromise> +>r12a : IPromise> +>r12.then(testFunction12, testFunction12, testFunction12) : IPromise> >r12.then : (success?: (value: (x: any) => any) => U, error?: (error: any) => U, progress?: (progress: any) => void) => IPromise >r12 : IPromise<(x: any) => any> >then : (success?: (value: (x: any) => any) => U, error?: (error: any) => U, progress?: (progress: any) => void) => IPromise @@ -1367,8 +1367,8 @@ var s12 = testFunction12(x => x); >x : any var s12a = s12.then(testFunction12, testFunction12, testFunction12); // ok ->s12a : IPromise> ->s12.then(testFunction12, testFunction12, testFunction12) : IPromise> +>s12a : IPromise> +>s12.then(testFunction12, testFunction12, testFunction12) : IPromise> >s12.then : (success?: (value: (x: any) => any) => U, error?: (error: any) => U, progress?: (progress: any) => void) => IPromise >s12 : IPromise<(x: any) => any> >then : (success?: (value: (x: any) => any) => U, error?: (error: any) => U, progress?: (progress: any) => void) => IPromise @@ -1387,8 +1387,8 @@ var s12b = s12.then(testFunction12P, testFunction12P, testFunction12P); // ok >testFunction12P : { (x: T): IPromise; (x: T, y: T): Promise; } var s12c = s12.then(testFunction12P, testFunction12, testFunction12); // ok ->s12c : IPromise> ->s12.then(testFunction12P, testFunction12, testFunction12) : IPromise> +>s12c : IPromise> +>s12.then(testFunction12P, testFunction12, testFunction12) : IPromise> >s12.then : (success?: (value: (x: any) => any) => U, error?: (error: any) => U, progress?: (progress: any) => void) => IPromise >s12 : IPromise<(x: any) => any> >then : (success?: (value: (x: any) => any) => U, error?: (error: any) => U, progress?: (progress: any) => void) => IPromise From 414f165df0ec099723a61d5702ca9aaf50dcbe3c Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Mon, 23 Oct 2017 12:36:44 -0700 Subject: [PATCH 3/7] Add tests --- .../reference/genericFunctionParameters.js | 34 ++++++++ .../genericFunctionParameters.symbols | 72 +++++++++++++++++ .../reference/genericFunctionParameters.types | 81 +++++++++++++++++++ .../genericFunctionParameters.ts | 15 ++++ 4 files changed, 202 insertions(+) create mode 100644 tests/baselines/reference/genericFunctionParameters.js create mode 100644 tests/baselines/reference/genericFunctionParameters.symbols create mode 100644 tests/baselines/reference/genericFunctionParameters.types create mode 100644 tests/cases/conformance/types/typeRelationships/typeInference/genericFunctionParameters.ts diff --git a/tests/baselines/reference/genericFunctionParameters.js b/tests/baselines/reference/genericFunctionParameters.js new file mode 100644 index 00000000000..55f4196e77b --- /dev/null +++ b/tests/baselines/reference/genericFunctionParameters.js @@ -0,0 +1,34 @@ +//// [genericFunctionParameters.ts] +declare function f1(cb: (x: S) => T): T; +declare function f2(cb: (x: S) => T): T; +declare function f3(cb: >(x: S) => T): T; + +let x1 = f1(x => x); // {} +let x2 = f2(x => x); // number +let x3 = f3(x => x); // Array + +// Repro from #19345 + +declare const s: (go: (ops: { init(): S; }) => R) => R; +const x = s(a => a.init()); // x is any, should have been {} + + +//// [genericFunctionParameters.js] +"use strict"; +var x1 = f1(function (x) { return x; }); // {} +var x2 = f2(function (x) { return x; }); // number +var x3 = f3(function (x) { return x; }); // Array +var x = s(function (a) { return a.init(); }); // x is any, should have been {} + + +//// [genericFunctionParameters.d.ts] +declare function f1(cb: (x: S) => T): T; +declare function f2(cb: (x: S) => T): T; +declare function f3(cb: >(x: S) => T): T; +declare let x1: {}; +declare let x2: number; +declare let x3: any[]; +declare const s: (go: (ops: { + init(): S; +}) => R) => R; +declare const x: {}; diff --git a/tests/baselines/reference/genericFunctionParameters.symbols b/tests/baselines/reference/genericFunctionParameters.symbols new file mode 100644 index 00000000000..c5955949289 --- /dev/null +++ b/tests/baselines/reference/genericFunctionParameters.symbols @@ -0,0 +1,72 @@ +=== tests/cases/conformance/types/typeRelationships/typeInference/genericFunctionParameters.ts === +declare function f1(cb: (x: S) => T): T; +>f1 : Symbol(f1, Decl(genericFunctionParameters.ts, 0, 0)) +>T : Symbol(T, Decl(genericFunctionParameters.ts, 0, 20)) +>cb : Symbol(cb, Decl(genericFunctionParameters.ts, 0, 23)) +>S : Symbol(S, Decl(genericFunctionParameters.ts, 0, 28)) +>x : Symbol(x, Decl(genericFunctionParameters.ts, 0, 31)) +>S : Symbol(S, Decl(genericFunctionParameters.ts, 0, 28)) +>T : Symbol(T, Decl(genericFunctionParameters.ts, 0, 20)) +>T : Symbol(T, Decl(genericFunctionParameters.ts, 0, 20)) + +declare function f2(cb: (x: S) => T): T; +>f2 : Symbol(f2, Decl(genericFunctionParameters.ts, 0, 46)) +>T : Symbol(T, Decl(genericFunctionParameters.ts, 1, 20)) +>cb : Symbol(cb, Decl(genericFunctionParameters.ts, 1, 23)) +>S : Symbol(S, Decl(genericFunctionParameters.ts, 1, 28)) +>x : Symbol(x, Decl(genericFunctionParameters.ts, 1, 46)) +>S : Symbol(S, Decl(genericFunctionParameters.ts, 1, 28)) +>T : Symbol(T, Decl(genericFunctionParameters.ts, 1, 20)) +>T : Symbol(T, Decl(genericFunctionParameters.ts, 1, 20)) + +declare function f3(cb: >(x: S) => T): T; +>f3 : Symbol(f3, Decl(genericFunctionParameters.ts, 1, 61)) +>T : Symbol(T, Decl(genericFunctionParameters.ts, 2, 20)) +>cb : Symbol(cb, Decl(genericFunctionParameters.ts, 2, 23)) +>S : Symbol(S, Decl(genericFunctionParameters.ts, 2, 28)) +>Array : Symbol(Array, Decl(lib.d.ts, --, --), Decl(lib.d.ts, --, --)) +>S : Symbol(S, Decl(genericFunctionParameters.ts, 2, 28)) +>x : Symbol(x, Decl(genericFunctionParameters.ts, 2, 48)) +>S : Symbol(S, Decl(genericFunctionParameters.ts, 2, 28)) +>T : Symbol(T, Decl(genericFunctionParameters.ts, 2, 20)) +>T : Symbol(T, Decl(genericFunctionParameters.ts, 2, 20)) + +let x1 = f1(x => x); // {} +>x1 : Symbol(x1, Decl(genericFunctionParameters.ts, 4, 3)) +>f1 : Symbol(f1, Decl(genericFunctionParameters.ts, 0, 0)) +>x : Symbol(x, Decl(genericFunctionParameters.ts, 4, 12)) +>x : Symbol(x, Decl(genericFunctionParameters.ts, 4, 12)) + +let x2 = f2(x => x); // number +>x2 : Symbol(x2, Decl(genericFunctionParameters.ts, 5, 3)) +>f2 : Symbol(f2, Decl(genericFunctionParameters.ts, 0, 46)) +>x : Symbol(x, Decl(genericFunctionParameters.ts, 5, 12)) +>x : Symbol(x, Decl(genericFunctionParameters.ts, 5, 12)) + +let x3 = f3(x => x); // Array +>x3 : Symbol(x3, Decl(genericFunctionParameters.ts, 6, 3)) +>f3 : Symbol(f3, Decl(genericFunctionParameters.ts, 1, 61)) +>x : Symbol(x, Decl(genericFunctionParameters.ts, 6, 12)) +>x : Symbol(x, Decl(genericFunctionParameters.ts, 6, 12)) + +// Repro from #19345 + +declare const s: (go: (ops: { init(): S; }) => R) => R; +>s : Symbol(s, Decl(genericFunctionParameters.ts, 10, 13)) +>R : Symbol(R, Decl(genericFunctionParameters.ts, 10, 18)) +>go : Symbol(go, Decl(genericFunctionParameters.ts, 10, 21)) +>S : Symbol(S, Decl(genericFunctionParameters.ts, 10, 26)) +>ops : Symbol(ops, Decl(genericFunctionParameters.ts, 10, 29)) +>init : Symbol(init, Decl(genericFunctionParameters.ts, 10, 35)) +>S : Symbol(S, Decl(genericFunctionParameters.ts, 10, 26)) +>R : Symbol(R, Decl(genericFunctionParameters.ts, 10, 18)) +>R : Symbol(R, Decl(genericFunctionParameters.ts, 10, 18)) + +const x = s(a => a.init()); // x is any, should have been {} +>x : Symbol(x, Decl(genericFunctionParameters.ts, 11, 5)) +>s : Symbol(s, Decl(genericFunctionParameters.ts, 10, 13)) +>a : Symbol(a, Decl(genericFunctionParameters.ts, 11, 12)) +>a.init : Symbol(init, Decl(genericFunctionParameters.ts, 10, 35)) +>a : Symbol(a, Decl(genericFunctionParameters.ts, 11, 12)) +>init : Symbol(init, Decl(genericFunctionParameters.ts, 10, 35)) + diff --git a/tests/baselines/reference/genericFunctionParameters.types b/tests/baselines/reference/genericFunctionParameters.types new file mode 100644 index 00000000000..3ae51c83e12 --- /dev/null +++ b/tests/baselines/reference/genericFunctionParameters.types @@ -0,0 +1,81 @@ +=== tests/cases/conformance/types/typeRelationships/typeInference/genericFunctionParameters.ts === +declare function f1(cb: (x: S) => T): T; +>f1 : (cb: (x: S) => T) => T +>T : T +>cb : (x: S) => T +>S : S +>x : S +>S : S +>T : T +>T : T + +declare function f2(cb: (x: S) => T): T; +>f2 : (cb: (x: S) => T) => T +>T : T +>cb : (x: S) => T +>S : S +>x : S +>S : S +>T : T +>T : T + +declare function f3(cb: >(x: S) => T): T; +>f3 : (cb: (x: S) => T) => T +>T : T +>cb : (x: S) => T +>S : S +>Array : T[] +>S : S +>x : S +>S : S +>T : T +>T : T + +let x1 = f1(x => x); // {} +>x1 : {} +>f1(x => x) : {} +>f1 : (cb: (x: S) => T) => T +>x => x : (x: S) => S +>x : S +>x : S + +let x2 = f2(x => x); // number +>x2 : number +>f2(x => x) : number +>f2 : (cb: (x: S) => T) => T +>x => x : (x: S) => S +>x : S +>x : S + +let x3 = f3(x => x); // Array +>x3 : any[] +>f3(x => x) : any[] +>f3 : (cb: (x: S) => T) => T +>x => x : (x: S) => S +>x : S +>x : S + +// Repro from #19345 + +declare const s: (go: (ops: { init(): S; }) => R) => R; +>s : (go: (ops: { init(): S; }) => R) => R +>R : R +>go : (ops: { init(): S; }) => R +>S : S +>ops : { init(): S; } +>init : () => S +>S : S +>R : R +>R : R + +const x = s(a => a.init()); // x is any, should have been {} +>x : {} +>s(a => a.init()) : {} +>s : (go: (ops: { init(): S; }) => R) => R +>a => a.init() : (a: { init(): S; }) => S +>a : { init(): S; } +>a.init() : S +>a.init : () => S +>a : { init(): S; } +>init : () => S + diff --git a/tests/cases/conformance/types/typeRelationships/typeInference/genericFunctionParameters.ts b/tests/cases/conformance/types/typeRelationships/typeInference/genericFunctionParameters.ts new file mode 100644 index 00000000000..e639f6b62b3 --- /dev/null +++ b/tests/cases/conformance/types/typeRelationships/typeInference/genericFunctionParameters.ts @@ -0,0 +1,15 @@ +// @strict: true +// @declaration: true + +declare function f1(cb: (x: S) => T): T; +declare function f2(cb: (x: S) => T): T; +declare function f3(cb: >(x: S) => T): T; + +let x1 = f1(x => x); // {} +let x2 = f2(x => x); // number +let x3 = f3(x => x); // Array + +// Repro from #19345 + +declare const s: (go: (ops: { init(): S; }) => R) => R; +const x = s(a => a.init()); // x is any, should have been {} From a9ffe0daeb74ed16ec67d6e147a8e2d95baf0e41 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 23 Oct 2017 13:35:53 -0700 Subject: [PATCH 4/7] Update issue_template to ts2.7 (#19422) --- issue_template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/issue_template.md b/issue_template.md index ddc1d070bc9..dbc021c28ad 100644 --- a/issue_template.md +++ b/issue_template.md @@ -3,7 +3,7 @@ -**TypeScript Version:** 2.6.0-dev.201xxxxx +**TypeScript Version:** 2.7.0-dev.201xxxxx **Code** From f916e38015648a412bc90c748dd08a5ef106a48a Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 23 Oct 2017 13:36:36 -0700 Subject: [PATCH 5/7] For @types installing quickfix, only activate for implicit-any module (#19394) --- src/services/codefixes/fixCannotFindModule.ts | 1 - tests/cases/fourslash/codeFixCannotFindModule.ts | 11 ++++++++++- .../fourslash/codeFixCannotFindModule_notIfMissing.ts | 11 +++++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 tests/cases/fourslash/codeFixCannotFindModule_notIfMissing.ts diff --git a/src/services/codefixes/fixCannotFindModule.ts b/src/services/codefixes/fixCannotFindModule.ts index b7fde9d917e..c15ca341cb4 100644 --- a/src/services/codefixes/fixCannotFindModule.ts +++ b/src/services/codefixes/fixCannotFindModule.ts @@ -2,7 +2,6 @@ namespace ts.codefix { registerCodeFix({ errorCodes: [ - Diagnostics.Cannot_find_module_0.code, Diagnostics.Could_not_find_a_declaration_file_for_module_0_1_implicitly_has_an_any_type.code, ], getCodeActions: context => { diff --git a/tests/cases/fourslash/codeFixCannotFindModule.ts b/tests/cases/fourslash/codeFixCannotFindModule.ts index 96e5c201644..d0ace09909e 100644 --- a/tests/cases/fourslash/codeFixCannotFindModule.ts +++ b/tests/cases/fourslash/codeFixCannotFindModule.ts @@ -1,11 +1,20 @@ /// -////import * as abs from "abs"; +// @moduleResolution: node +// @noImplicitAny: true + +// @Filename: /node_modules/abs/index.js +////not read + +// @Filename: /a.ts +/////**/import * as abs from "abs"; test.setTypesRegistry({ "abs": undefined, }); +goTo.marker(); + verify.codeFixAvailable([{ description: "Install '@types/abs'", commands: [{ diff --git a/tests/cases/fourslash/codeFixCannotFindModule_notIfMissing.ts b/tests/cases/fourslash/codeFixCannotFindModule_notIfMissing.ts new file mode 100644 index 00000000000..f446c643542 --- /dev/null +++ b/tests/cases/fourslash/codeFixCannotFindModule_notIfMissing.ts @@ -0,0 +1,11 @@ +/// + +// @Filename: /a.ts +////import * as abs from "abs"; + +test.setTypesRegistry({ + "abs": undefined, +}); + +// We only give the fix for an implicit-any module, not for a missing module. +verify.not.codeFixAvailable(); From 159a0a21973cd882fb04d01335aaf7a12bc7ad45 Mon Sep 17 00:00:00 2001 From: Andy Date: Mon, 23 Oct 2017 13:38:50 -0700 Subject: [PATCH 6/7] Use NodeFlags to detect nodes inside with statements instead of climbing ancestors (#17721) * Use NodeFlags to detect nodes inside with statements instead of climbing ancestors * Add to ContextFlags --- src/compiler/checker.ts | 23 +++++------------------ src/compiler/parser.ts | 2 +- src/compiler/types.ts | 3 ++- 3 files changed, 8 insertions(+), 20 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6938ed8d77f..aaaa0ed50b8 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -13440,7 +13440,7 @@ namespace ts { // exists. Otherwise, it is the type of the string index signature in T, if one exists. function getContextualTypeForObjectLiteralMethod(node: MethodDeclaration): Type { Debug.assert(isObjectLiteralMethod(node)); - if (isInsideWithStatementBody(node)) { + if (node.flags & NodeFlags.InWithStatement) { // We cannot answer semantic questions within a with block, do not proceed any further return undefined; } @@ -13559,7 +13559,7 @@ namespace ts { * @returns the contextual type of an expression. */ function getContextualType(node: Expression): Type | undefined { - if (isInsideWithStatementBody(node)) { + if (node.flags & NodeFlags.InWithStatement) { // We cannot answer semantic questions within a with block, do not proceed any further return undefined; } @@ -23124,21 +23124,8 @@ namespace ts { // Language service support - function isInsideWithStatementBody(node: Node): boolean { - if (node) { - while (node.parent) { - if (node.parent.kind === SyntaxKind.WithStatement && (node.parent).statement === node) { - return true; - } - node = node.parent; - } - } - - return false; - } - function getSymbolsInScope(location: Node, meaning: SymbolFlags): Symbol[] { - if (isInsideWithStatementBody(location)) { + if (location.flags & NodeFlags.InWithStatement) { // We cannot answer semantic questions within a with block, do not proceed any further return []; } @@ -23438,7 +23425,7 @@ namespace ts { return isExternalModule(node) ? getMergedSymbol(node.symbol) : undefined; } - if (isInsideWithStatementBody(node)) { + if (node.flags & NodeFlags.InWithStatement) { // We cannot answer semantic questions within a with block, do not proceed any further return undefined; } @@ -23546,7 +23533,7 @@ namespace ts { } function getTypeOfNode(node: Node): Type { - if (isInsideWithStatementBody(node)) { + if (node.flags & NodeFlags.InWithStatement) { // We cannot answer semantic questions within a with block, do not proceed any further return unknownType; } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index e2bae71e6bf..b27d4811ecb 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -4724,7 +4724,7 @@ namespace ts { parseExpected(SyntaxKind.OpenParenToken); node.expression = allowInAnd(parseExpression); parseExpected(SyntaxKind.CloseParenToken); - node.statement = parseStatement(); + node.statement = doInsideOfContext(NodeFlags.InWithStatement, parseStatement); return finishNode(node); } diff --git a/src/compiler/types.ts b/src/compiler/types.ts index fb59c9eb881..c7030450a75 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -451,6 +451,7 @@ namespace ts { /* @internal */ PossiblyContainsDynamicImport = 1 << 19, JSDoc = 1 << 20, // If node was parsed inside jsdoc + InWithStatement = 1 << 21, // If any ancestor of node was the `statement` of a WithStatement (not the `expression`) BlockScoped = Let | Const, @@ -458,7 +459,7 @@ namespace ts { ReachabilityAndEmitFlags = ReachabilityCheckFlags | HasAsyncFunctions, // Parsing context flags - ContextFlags = DisallowInContext | YieldContext | DecoratorContext | AwaitContext | JavaScriptFile, + ContextFlags = DisallowInContext | YieldContext | DecoratorContext | AwaitContext | JavaScriptFile | InWithStatement, // Exclude these flags when parsing a Type TypeExcludesFlags = YieldContext | AwaitContext, From fa3ce9fe6ca9c8b8d12ecd35cdceebdd3cec10fc Mon Sep 17 00:00:00 2001 From: Wesley Wigham Date: Mon, 23 Oct 2017 14:28:20 -0700 Subject: [PATCH 7/7] Fix build break (#19431) --- src/compiler/types.ts | 2 +- tests/baselines/reference/api/tsserverlibrary.d.ts | 2 +- tests/baselines/reference/api/typescript.d.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/compiler/types.ts b/src/compiler/types.ts index c7030450a75..ff2a33266ed 100644 --- a/src/compiler/types.ts +++ b/src/compiler/types.ts @@ -451,7 +451,7 @@ namespace ts { /* @internal */ PossiblyContainsDynamicImport = 1 << 19, JSDoc = 1 << 20, // If node was parsed inside jsdoc - InWithStatement = 1 << 21, // If any ancestor of node was the `statement` of a WithStatement (not the `expression`) + /* @internal */ InWithStatement = 1 << 21, // If any ancestor of node was the `statement` of a WithStatement (not the `expression`) BlockScoped = Let | Const, diff --git a/tests/baselines/reference/api/tsserverlibrary.d.ts b/tests/baselines/reference/api/tsserverlibrary.d.ts index 62f4f68d148..0f20bfc8687 100644 --- a/tests/baselines/reference/api/tsserverlibrary.d.ts +++ b/tests/baselines/reference/api/tsserverlibrary.d.ts @@ -408,7 +408,7 @@ declare namespace ts { BlockScoped = 3, ReachabilityCheckFlags = 384, ReachabilityAndEmitFlags = 1408, - ContextFlags = 96256, + ContextFlags = 2193408, TypeExcludesFlags = 20480, } enum ModifierFlags { diff --git a/tests/baselines/reference/api/typescript.d.ts b/tests/baselines/reference/api/typescript.d.ts index c7c8ba88d72..67a30bcd371 100644 --- a/tests/baselines/reference/api/typescript.d.ts +++ b/tests/baselines/reference/api/typescript.d.ts @@ -408,7 +408,7 @@ declare namespace ts { BlockScoped = 3, ReachabilityCheckFlags = 384, ReachabilityAndEmitFlags = 1408, - ContextFlags = 96256, + ContextFlags = 2193408, TypeExcludesFlags = 20480, } enum ModifierFlags {