Skip to content

Commit bfe63cc

Browse files
Merge pull request #1648 from Microsoft/contextualTypeParenthesizedExpressions
Contextually type parenthesized expressions
2 parents d391a8a + 6783e35 commit bfe63cc

18 files changed

+1146
-40
lines changed

src/compiler/checker.ts

+4
Original file line numberDiff line numberDiff line change
@@ -3337,6 +3337,8 @@ module ts {
33373337
case SyntaxKind.MethodDeclaration:
33383338
case SyntaxKind.MethodSignature:
33393339
return isContextSensitiveFunctionLikeDeclaration(<MethodDeclaration>node);
3340+
case SyntaxKind.ParenthesizedExpression:
3341+
return isContextSensitive((<ParenthesizedExpression>node).expression);
33403342
}
33413343

33423344
return false;
@@ -5229,6 +5231,8 @@ module ts {
52295231
case SyntaxKind.TemplateSpan:
52305232
Debug.assert(parent.parent.kind === SyntaxKind.TemplateExpression);
52315233
return getContextualTypeForSubstitutionExpression(<TemplateExpression>parent.parent, node);
5234+
case SyntaxKind.ParenthesizedExpression:
5235+
return getContextualType(<ParenthesizedExpression>parent);
52325236
}
52335237
return undefined;
52345238
}

tests/baselines/reference/castTest.types

+12-12
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ var p_cast = <Point> ({
6565
>p_cast : Point
6666
><Point> ({ x: 0, y: 0, add: function(dx, dy) { return new Point(this.x + dx, this.y + dy); }, mult: function(p) { return p; }}) : Point
6767
>Point : Point
68-
>({ x: 0, y: 0, add: function(dx, dy) { return new Point(this.x + dx, this.y + dy); }, mult: function(p) { return p; }}) : { x: number; y: number; add: (dx: any, dy: any) => Point; mult: (p: any) => any; }
69-
>{ x: 0, y: 0, add: function(dx, dy) { return new Point(this.x + dx, this.y + dy); }, mult: function(p) { return p; }} : { x: number; y: number; add: (dx: any, dy: any) => Point; mult: (p: any) => any; }
68+
>({ x: 0, y: 0, add: function(dx, dy) { return new Point(this.x + dx, this.y + dy); }, mult: function(p) { return p; }}) : { x: number; y: number; add: (dx: number, dy: number) => Point; mult: (p: Point) => Point; }
69+
>{ x: 0, y: 0, add: function(dx, dy) { return new Point(this.x + dx, this.y + dy); }, mult: function(p) { return p; }} : { x: number; y: number; add: (dx: number, dy: number) => Point; mult: (p: Point) => Point; }
7070

7171
x: 0,
7272
>x : number
@@ -75,10 +75,10 @@ var p_cast = <Point> ({
7575
>y : number
7676

7777
add: function(dx, dy) {
78-
>add : (dx: any, dy: any) => Point
79-
>function(dx, dy) { return new Point(this.x + dx, this.y + dy); } : (dx: any, dy: any) => Point
80-
>dx : any
81-
>dy : any
78+
>add : (dx: number, dy: number) => Point
79+
>function(dx, dy) { return new Point(this.x + dx, this.y + dy); } : (dx: number, dy: number) => Point
80+
>dx : number
81+
>dy : number
8282

8383
return new Point(this.x + dx, this.y + dy);
8484
>new Point(this.x + dx, this.y + dy) : Point
@@ -87,19 +87,19 @@ var p_cast = <Point> ({
8787
>this.x : any
8888
>this : any
8989
>x : any
90-
>dx : any
90+
>dx : number
9191
>this.y + dy : any
9292
>this.y : any
9393
>this : any
9494
>y : any
95-
>dy : any
95+
>dy : number
9696

9797
},
9898
mult: function(p) { return p; }
99-
>mult : (p: any) => any
100-
>function(p) { return p; } : (p: any) => any
101-
>p : any
102-
>p : any
99+
>mult : (p: Point) => Point
100+
>function(p) { return p; } : (p: Point) => Point
101+
>p : Point
102+
>p : Point
103103

104104
})
105105

Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
tests/cases/compiler/contextualTypingWithFixedTypeParameters1.ts(2,22): error TS2339: Property 'foo' does not exist on type 'string'.
2+
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.
3+
Type argument candidate 'string' is not a valid type argument because it is not a supertype of candidate 'T'.
4+
tests/cases/compiler/contextualTypingWithFixedTypeParameters1.ts(3,32): error TS2339: Property 'foo' does not exist on type 'T'.
25

36

4-
==== tests/cases/compiler/contextualTypingWithFixedTypeParameters1.ts (1 errors) ====
7+
==== tests/cases/compiler/contextualTypingWithFixedTypeParameters1.ts (3 errors) ====
58
var f10: <T>(x: T, b: () => (a: T) => void, y: T) => T;
69
f10('', () => a => a.foo, ''); // a is string
710
~~~
811
!!! error TS2339: Property 'foo' does not exist on type 'string'.
9-
var r9 = f10('', () => (a => a.foo), 1); // error
12+
var r9 = f10('', () => (a => a.foo), 1); // error
13+
~~~
14+
!!! error TS2453: The type argument for type parameter 'T' cannot be inferred from the usage. Consider specifying the type arguments explicitly.
15+
!!! error TS2453: Type argument candidate 'string' is not a valid type argument because it is not a supertype of candidate 'T'.
16+
~~~
17+
!!! error TS2339: Property 'foo' does not exist on type 'T'.

tests/baselines/reference/logicalOrExpressionIsNotContextuallyTyped.types

+9-9
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,14 @@ var a: (a: string) => string;
1111

1212
// bug 786110
1313
var r = a || ((a) => a.toLowerCase());
14-
>r : (a: any) => any
15-
>a || ((a) => a.toLowerCase()) : (a: any) => any
14+
>r : (a: string) => string
15+
>a || ((a) => a.toLowerCase()) : (a: string) => string
1616
>a : (a: string) => string
17-
>((a) => a.toLowerCase()) : (a: any) => any
18-
>(a) => a.toLowerCase() : (a: any) => any
19-
>a : any
20-
>a.toLowerCase() : any
21-
>a.toLowerCase : any
22-
>a : any
23-
>toLowerCase : any
17+
>((a) => a.toLowerCase()) : (a: string) => string
18+
>(a) => a.toLowerCase() : (a: string) => string
19+
>a : string
20+
>a.toLowerCase() : string
21+
>a.toLowerCase : () => string
22+
>a : string
23+
>toLowerCase : () => string
2424

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//// [parenthesizedContexualTyping1.ts]
2+
3+
function fun<T>(g: (x: T) => T, x: T): T;
4+
function fun<T>(g: (x: T) => T, h: (y: T) => T, x: T): T;
5+
function fun<T>(g: (x: T) => T, x: T): T {
6+
return g(x);
7+
}
8+
9+
var a = fun(x => x, 10);
10+
var b = fun((x => x), 10);
11+
var c = fun(((x => x)), 10);
12+
var d = fun((((x => x))), 10);
13+
14+
var e = fun(x => x, x => x, 10);
15+
var f = fun((x => x), (x => x), 10);
16+
var g = fun(((x => x)), ((x => x)), 10);
17+
var h = fun((((x => x))), ((x => x)), 10);
18+
19+
// Ternaries in parens
20+
var i = fun((Math.random() < 0.5 ? x => x : x => undefined), 10);
21+
var j = fun((Math.random() < 0.5 ? (x => x) : (x => undefined)), 10);
22+
var k = fun((Math.random() < 0.5 ? (x => x) : (x => undefined)), x => x, 10);
23+
var l = fun(((Math.random() < 0.5 ? ((x => x)) : ((x => undefined)))), ((x => x)), 10);
24+
25+
var lambda1: (x: number) => number = x => x;
26+
var lambda2: (x: number) => number = (x => x);
27+
28+
type ObjType = { x: (p: number) => string; y: (p: string) => number };
29+
var obj1: ObjType = { x: x => (x, undefined), y: y => (y, undefined) };
30+
var obj2: ObjType = ({ x: x => (x, undefined), y: y => (y, undefined) });
31+
32+
//// [parenthesizedContexualTyping1.js]
33+
function fun(g, x) {
34+
return g(x);
35+
}
36+
var a = fun(function (x) { return x; }, 10);
37+
var b = fun((function (x) { return x; }), 10);
38+
var c = fun(((function (x) { return x; })), 10);
39+
var d = fun((((function (x) { return x; }))), 10);
40+
var e = fun(function (x) { return x; }, function (x) { return x; }, 10);
41+
var f = fun((function (x) { return x; }), (function (x) { return x; }), 10);
42+
var g = fun(((function (x) { return x; })), ((function (x) { return x; })), 10);
43+
var h = fun((((function (x) { return x; }))), ((function (x) { return x; })), 10);
44+
// Ternaries in parens
45+
var i = fun((Math.random() < 0.5 ? function (x) { return x; } : function (x) { return undefined; }), 10);
46+
var j = fun((Math.random() < 0.5 ? (function (x) { return x; }) : (function (x) { return undefined; })), 10);
47+
var k = fun((Math.random() < 0.5 ? (function (x) { return x; }) : (function (x) { return undefined; })), function (x) { return x; }, 10);
48+
var l = fun(((Math.random() < 0.5 ? ((function (x) { return x; })) : ((function (x) { return undefined; })))), ((function (x) { return x; })), 10);
49+
var lambda1 = function (x) { return x; };
50+
var lambda2 = (function (x) { return x; });
51+
var obj1 = { x: function (x) { return (x, undefined); }, y: function (y) { return (y, undefined); } };
52+
var obj2 = ({ x: function (x) { return (x, undefined); }, y: function (y) { return (y, undefined); } });

0 commit comments

Comments
 (0)