From d2f500292f8cb885ec8e379944ae272af911210d Mon Sep 17 00:00:00 2001 From: Anders Hejlsberg Date: Wed, 10 Dec 2014 16:02:39 -0800 Subject: [PATCH] Make initial inferences from parameterless function expressions (#1186) --- src/compiler/checker.ts | 2 +- ...lTypingWithFixedTypeParameters1.errors.txt | 9 +---- .../inferenceFromParameterlessLambda.js | 17 +++++++++ .../inferenceFromParameterlessLambda.types | 37 +++++++++++++++++++ .../inferenceFromParameterlessLambda.ts | 9 +++++ 5 files changed, 66 insertions(+), 8 deletions(-) create mode 100644 tests/baselines/reference/inferenceFromParameterlessLambda.js create mode 100644 tests/baselines/reference/inferenceFromParameterlessLambda.types create mode 100644 tests/cases/compiler/inferenceFromParameterlessLambda.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 1e8a87bc4d4..41a0a3c4ec2 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -3372,7 +3372,7 @@ module ts { } function isContextSensitiveFunctionLikeDeclaration(node: FunctionLikeDeclaration) { - return !node.typeParameters && !forEach(node.parameters, p => p.type); + return !node.typeParameters && node.parameters.length && !forEach(node.parameters, p => p.type); } function getTypeWithoutConstructors(type: Type): Type { diff --git a/tests/baselines/reference/contextualTypingWithFixedTypeParameters1.errors.txt b/tests/baselines/reference/contextualTypingWithFixedTypeParameters1.errors.txt index b668468eac3..972b4bb9188 100644 --- a/tests/baselines/reference/contextualTypingWithFixedTypeParameters1.errors.txt +++ b/tests/baselines/reference/contextualTypingWithFixedTypeParameters1.errors.txt @@ -1,14 +1,9 @@ tests/cases/compiler/contextualTypingWithFixedTypeParameters1.ts(2,22): error TS2339: Property 'foo' does not exist on type 'string'. -tests/cases/compiler/contextualTypingWithFixedTypeParameters1.ts(3,10): error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. - Type argument candidate 'string' is not a valid type argument because it is not a supertype of candidate 'number'. -==== tests/cases/compiler/contextualTypingWithFixedTypeParameters1.ts (2 errors) ==== +==== tests/cases/compiler/contextualTypingWithFixedTypeParameters1.ts (1 errors) ==== var f10: (x: T, b: () => (a: T) => void, y: T) => T; f10('', () => a => a.foo, ''); // a is string ~~~ !!! error TS2339: Property 'foo' does not exist on type 'string'. - var r9 = f10('', () => (a => a.foo), 1); // error - ~~~ -!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly. -!!! error TS2453: Type argument candidate 'string' is not a valid type argument because it is not a supertype of candidate 'number'. \ No newline at end of file + var r9 = f10('', () => (a => a.foo), 1); // error \ No newline at end of file diff --git a/tests/baselines/reference/inferenceFromParameterlessLambda.js b/tests/baselines/reference/inferenceFromParameterlessLambda.js new file mode 100644 index 00000000000..ad9a18b7549 --- /dev/null +++ b/tests/baselines/reference/inferenceFromParameterlessLambda.js @@ -0,0 +1,17 @@ +//// [inferenceFromParameterlessLambda.ts] +function foo(o: Take, i: Make) { } +interface Make { + (): T; +} +interface Take { + (n: T): void; +} +// Infer string from second argument because it isn't context sensitive +foo(n => n.length, () => 'hi'); + + +//// [inferenceFromParameterlessLambda.js] +function foo(o, i) { +} +// Infer string from second argument because it isn't context sensitive +foo(function (n) { return n.length; }, function () { return 'hi'; }); diff --git a/tests/baselines/reference/inferenceFromParameterlessLambda.types b/tests/baselines/reference/inferenceFromParameterlessLambda.types new file mode 100644 index 00000000000..8dbb8c5967c --- /dev/null +++ b/tests/baselines/reference/inferenceFromParameterlessLambda.types @@ -0,0 +1,37 @@ +=== tests/cases/compiler/inferenceFromParameterlessLambda.ts === +function foo(o: Take, i: Make) { } +>foo : (o: Take, i: Make) => void +>T : T +>o : Take +>Take : Take +>T : T +>i : Make +>Make : Make +>T : T + +interface Make { +>Make : Make +>T : T + + (): T; +>T : T +} +interface Take { +>Take : Take +>T : T + + (n: T): void; +>n : T +>T : T +} +// Infer string from second argument because it isn't context sensitive +foo(n => n.length, () => 'hi'); +>foo(n => n.length, () => 'hi') : void +>foo : (o: Take, i: Make) => void +>n => n.length : (n: string) => number +>n : string +>n.length : number +>n : string +>length : number +>() => 'hi' : () => string + diff --git a/tests/cases/compiler/inferenceFromParameterlessLambda.ts b/tests/cases/compiler/inferenceFromParameterlessLambda.ts new file mode 100644 index 00000000000..8585d4451fd --- /dev/null +++ b/tests/cases/compiler/inferenceFromParameterlessLambda.ts @@ -0,0 +1,9 @@ +function foo(o: Take, i: Make) { } +interface Make { + (): T; +} +interface Take { + (n: T): void; +} +// Infer string from second argument because it isn't context sensitive +foo(n => n.length, () => 'hi');