Skip to content

Commit 5602766

Browse files
Initial work on overload resolution with tagged templates.
Currently type argument inference breaks hard when the first parameter of a tag has a generic type.
1 parent 0a97f5f commit 5602766

31 files changed

+500
-167
lines changed

src/compiler/checker.ts

Lines changed: 153 additions & 53 deletions
Large diffs are not rendered by default.

src/compiler/core.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,17 @@ module ts {
122122
return result;
123123
}
124124

125+
/**
126+
* Returns the last element of an array if non-empty, undefined otherwise.
127+
*/
128+
export function lastOrUndefined<T>(array: T[]): T {
129+
if (array.length === 0) {
130+
return undefined;
131+
}
132+
133+
return array[array.length - 1];
134+
}
135+
125136
export function binarySearch(array: number[], value: number): number {
126137
var low = 0;
127138
var high = array.length - 1;

src/lib/core.d.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,10 @@ declare var Number: {
484484
POSITIVE_INFINITY: number;
485485
}
486486

487+
interface TemplateStringsArray extends Array<string> {
488+
raw: string[];
489+
}
490+
487491
interface Math {
488492
/** The mathematical constant e. This is Euler's number, the base of natural logarithms. */
489493
E: number;

tests/baselines/reference/noDefaultLib.errors.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
error TS2318: Cannot find global type 'Boolean'.
22
error TS2318: Cannot find global type 'IArguments'.
3+
error TS2318: Cannot find global type 'TemplateStringsArray'.
34
tests/cases/compiler/noDefaultLib.ts(4,11): error TS2317: Global type 'Array' must have 1 type parameter(s).
45

56

67
!!! error TS2318: Cannot find global type 'Boolean'.
78
!!! error TS2318: Cannot find global type 'IArguments'.
9+
!!! error TS2318: Cannot find global type 'TemplateStringsArray'.
810
==== tests/cases/compiler/noDefaultLib.ts (1 errors) ====
911
/// <reference no-default-lib="true"/>
1012
var x;

tests/baselines/reference/parser509698.errors.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ error TS2318: Cannot find global type 'Number'.
66
error TS2318: Cannot find global type 'Object'.
77
error TS2318: Cannot find global type 'RegExp'.
88
error TS2318: Cannot find global type 'String'.
9+
error TS2318: Cannot find global type 'TemplateStringsArray'.
910

1011

1112
!!! error TS2318: Cannot find global type 'Array'.
@@ -16,6 +17,7 @@ error TS2318: Cannot find global type 'String'.
1617
!!! error TS2318: Cannot find global type 'Object'.
1718
!!! error TS2318: Cannot find global type 'RegExp'.
1819
!!! error TS2318: Cannot find global type 'String'.
20+
!!! error TS2318: Cannot find global type 'TemplateStringsArray'.
1921
==== tests/cases/conformance/parser/ecmascript5/RegressionTests/parser509698.ts (0 errors) ====
2022
/// <style requireSemi="on" />
2123
/// <reference no-default-lib="true"/>

tests/baselines/reference/project/noDefaultLib/amd/noDefaultLib.errors.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ error TS2318: Cannot find global type 'Number'.
66
error TS2318: Cannot find global type 'Object'.
77
error TS2318: Cannot find global type 'RegExp'.
88
error TS2318: Cannot find global type 'String'.
9+
error TS2318: Cannot find global type 'TemplateStringsArray'.
910
test.ts(3,8): error TS2304: Cannot find name 'Array'.
1011

1112

@@ -17,6 +18,7 @@ test.ts(3,8): error TS2304: Cannot find name 'Array'.
1718
!!! error TS2318: Cannot find global type 'Object'.
1819
!!! error TS2318: Cannot find global type 'RegExp'.
1920
!!! error TS2318: Cannot find global type 'String'.
21+
!!! error TS2318: Cannot find global type 'TemplateStringsArray'.
2022
==== test.ts (1 errors) ====
2123
/// <reference no-default-lib="true"/>
2224

tests/baselines/reference/project/noDefaultLib/node/noDefaultLib.errors.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ error TS2318: Cannot find global type 'Number'.
66
error TS2318: Cannot find global type 'Object'.
77
error TS2318: Cannot find global type 'RegExp'.
88
error TS2318: Cannot find global type 'String'.
9+
error TS2318: Cannot find global type 'TemplateStringsArray'.
910
test.ts(3,8): error TS2304: Cannot find name 'Array'.
1011

1112

@@ -17,6 +18,7 @@ test.ts(3,8): error TS2304: Cannot find name 'Array'.
1718
!!! error TS2318: Cannot find global type 'Object'.
1819
!!! error TS2318: Cannot find global type 'RegExp'.
1920
!!! error TS2318: Cannot find global type 'String'.
21+
!!! error TS2318: Cannot find global type 'TemplateStringsArray'.
2022
==== test.ts (1 errors) ====
2123
/// <reference no-default-lib="true"/>
2224

tests/baselines/reference/taggedTemplateStringsWithIncompatibleTypedTags.errors.txt

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,17 @@ tests/cases/conformance/es6/templates/taggedTemplateStringsWithIncompatibleTyped
88
tests/cases/conformance/es6/templates/taggedTemplateStringsWithIncompatibleTypedTags.ts(24,1): error TS1160: Tagged templates are only available when targeting ECMAScript 6 and higher.
99
tests/cases/conformance/es6/templates/taggedTemplateStringsWithIncompatibleTypedTags.ts(26,1): error TS1160: Tagged templates are only available when targeting ECMAScript 6 and higher.
1010
tests/cases/conformance/es6/templates/taggedTemplateStringsWithIncompatibleTypedTags.ts(26,1): error TS1160: Tagged templates are only available when targeting ECMAScript 6 and higher.
11+
tests/cases/conformance/es6/templates/taggedTemplateStringsWithIncompatibleTypedTags.ts(28,1): error TS1160: Tagged templates are only available when targeting ECMAScript 6 and higher.
12+
tests/cases/conformance/es6/templates/taggedTemplateStringsWithIncompatibleTypedTags.ts(28,1): error TS1160: Tagged templates are only available when targeting ECMAScript 6 and higher.
13+
tests/cases/conformance/es6/templates/taggedTemplateStringsWithIncompatibleTypedTags.ts(14,9): error TS2345: Argument of type 'number' is not assignable to parameter of type 'boolean'.
14+
tests/cases/conformance/es6/templates/taggedTemplateStringsWithIncompatibleTypedTags.ts(18,9): error TS2345: Argument of type 'number' is not assignable to parameter of type 'boolean'.
15+
tests/cases/conformance/es6/templates/taggedTemplateStringsWithIncompatibleTypedTags.ts(22,9): error TS2345: Argument of type 'number' is not assignable to parameter of type 'boolean'.
16+
tests/cases/conformance/es6/templates/taggedTemplateStringsWithIncompatibleTypedTags.ts(24,25): error TS2345: Argument of type 'number' is not assignable to parameter of type 'boolean'.
17+
tests/cases/conformance/es6/templates/taggedTemplateStringsWithIncompatibleTypedTags.ts(26,9): error TS2345: Argument of type 'number' is not assignable to parameter of type 'boolean'.
18+
tests/cases/conformance/es6/templates/taggedTemplateStringsWithIncompatibleTypedTags.ts(28,57): error TS2345: Argument of type 'number' is not assignable to parameter of type 'boolean'.
1119

1220

13-
==== tests/cases/conformance/es6/templates/taggedTemplateStringsWithIncompatibleTypedTags.ts (10 errors) ====
21+
==== tests/cases/conformance/es6/templates/taggedTemplateStringsWithIncompatibleTypedTags.ts (18 errors) ====
1422
interface I {
1523
(stringParts: string[], ...rest: boolean[]): I;
1624
g: I;
@@ -29,6 +37,8 @@ tests/cases/conformance/es6/templates/taggedTemplateStringsWithIncompatibleTyped
2937
f `abc${1}def${2}ghi`;
3038
~~~~~~~~~~~~~~~~~~~~~
3139
!!! error TS1160: Tagged templates are only available when targeting ECMAScript 6 and higher.
40+
~
41+
!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'boolean'.
3242

3343
f `abc`.member
3444
~~~~~~~
@@ -37,6 +47,8 @@ tests/cases/conformance/es6/templates/taggedTemplateStringsWithIncompatibleTyped
3747
f `abc${1}def${2}ghi`.member;
3848
~~~~~~~~~~~~~~~~~~~~~
3949
!!! error TS1160: Tagged templates are only available when targeting ECMAScript 6 and higher.
50+
~
51+
!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'boolean'.
4052

4153
f `abc`["member"];
4254
~~~~~~~
@@ -45,18 +57,32 @@ tests/cases/conformance/es6/templates/taggedTemplateStringsWithIncompatibleTyped
4557
f `abc${1}def${2}ghi`["member"];
4658
~~~~~~~~~~~~~~~~~~~~~
4759
!!! error TS1160: Tagged templates are only available when targeting ECMAScript 6 and higher.
60+
~
61+
!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'boolean'.
4862

4963
f `abc`[0].member `abc${1}def${2}ghi`;
5064
~~~~~~~
5165
!!! error TS1160: Tagged templates are only available when targeting ECMAScript 6 and higher.
5266
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5367
!!! error TS1160: Tagged templates are only available when targeting ECMAScript 6 and higher.
68+
~
69+
!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'boolean'.
5470

5571
f `abc${1}def${2}ghi`["member"].member `abc${1}def${2}ghi`;
5672
~~~~~~~~~~~~~~~~~~~~~
5773
!!! error TS1160: Tagged templates are only available when targeting ECMAScript 6 and higher.
5874
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5975
!!! error TS1160: Tagged templates are only available when targeting ECMAScript 6 and higher.
76+
~
77+
!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'boolean'.
78+
79+
f `abc${ true }def${ true }ghi`["member"].member `abc${ 1 }def${ 2 }ghi`;
80+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
81+
!!! error TS1160: Tagged templates are only available when targeting ECMAScript 6 and higher.
82+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
83+
!!! error TS1160: Tagged templates are only available when targeting ECMAScript 6 and higher.
84+
~
85+
!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'boolean'.
6086

6187
f.thisIsNotATag(`abc`);
6288

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
tests/cases/conformance/es6/templates/taggedTemplateStringsWithIncompatibleTypedTagsES6.ts(14,9): error TS2345: Argument of type 'number' is not assignable to parameter of type 'boolean'.
2+
tests/cases/conformance/es6/templates/taggedTemplateStringsWithIncompatibleTypedTagsES6.ts(18,9): error TS2345: Argument of type 'number' is not assignable to parameter of type 'boolean'.
3+
tests/cases/conformance/es6/templates/taggedTemplateStringsWithIncompatibleTypedTagsES6.ts(22,9): error TS2345: Argument of type 'number' is not assignable to parameter of type 'boolean'.
4+
tests/cases/conformance/es6/templates/taggedTemplateStringsWithIncompatibleTypedTagsES6.ts(24,25): error TS2345: Argument of type 'number' is not assignable to parameter of type 'boolean'.
5+
tests/cases/conformance/es6/templates/taggedTemplateStringsWithIncompatibleTypedTagsES6.ts(26,9): error TS2345: Argument of type 'number' is not assignable to parameter of type 'boolean'.
6+
tests/cases/conformance/es6/templates/taggedTemplateStringsWithIncompatibleTypedTagsES6.ts(28,57): error TS2345: Argument of type 'number' is not assignable to parameter of type 'boolean'.
7+
8+
9+
==== tests/cases/conformance/es6/templates/taggedTemplateStringsWithIncompatibleTypedTagsES6.ts (6 errors) ====
10+
interface I {
11+
(stringParts: string[], ...rest: boolean[]): I;
12+
g: I;
13+
h: I;
14+
member: I;
15+
thisIsNotATag(x: string): void
16+
[x: number]: I;
17+
}
18+
19+
var f: I;
20+
21+
f `abc`
22+
23+
f `abc${1}def${2}ghi`;
24+
~
25+
!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'boolean'.
26+
27+
f `abc`.member
28+
29+
f `abc${1}def${2}ghi`.member;
30+
~
31+
!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'boolean'.
32+
33+
f `abc`["member"];
34+
35+
f `abc${1}def${2}ghi`["member"];
36+
~
37+
!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'boolean'.
38+
39+
f `abc`[0].member `abc${1}def${2}ghi`;
40+
~
41+
!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'boolean'.
42+
43+
f `abc${1}def${2}ghi`["member"].member `abc${1}def${2}ghi`;
44+
~
45+
!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'boolean'.
46+
47+
f `abc${ true }def${ true }ghi`["member"].member `abc${ 1 }def${ 2 }ghi`;
48+
~
49+
!!! error TS2345: Argument of type 'number' is not assignable to parameter of type 'boolean'.
50+
51+
f.thisIsNotATag(`abc`);
52+
53+
f.thisIsNotATag(`abc${1}def${2}ghi`);

tests/baselines/reference/taggedTemplateStringsWithIncompatibleTypedTagsES6.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,11 @@ f `abc`[0].member `abc${1}def${2}ghi`;
2626

2727
f `abc${1}def${2}ghi`["member"].member `abc${1}def${2}ghi`;
2828

29+
f `abc${ true }def${ true }ghi`["member"].member `abc${ 1 }def${ 2 }ghi`;
30+
2931
f.thisIsNotATag(`abc`);
3032

31-
f.thisIsNotATag(`abc${1}def${2}ghi`);
32-
33+
f.thisIsNotATag(`abc${1}def${2}ghi`);
3334

3435
//// [taggedTemplateStringsWithIncompatibleTypedTagsES6.js]
3536
var f;
@@ -41,5 +42,6 @@ f `abc`["member"];
4142
f `abc${1}def${2}ghi`["member"];
4243
f `abc`[0].member `abc${1}def${2}ghi`;
4344
f `abc${1}def${2}ghi`["member"].member `abc${1}def${2}ghi`;
45+
f `abc${true}def${true}ghi`["member"].member `abc${1}def${2}ghi`;
4446
f.thisIsNotATag(`abc`);
4547
f.thisIsNotATag(`abc${1}def${2}ghi`);

tests/baselines/reference/taggedTemplateStringsWithIncompatibleTypedTagsES6.types

Lines changed: 0 additions & 82 deletions
This file was deleted.

tests/baselines/reference/taggedTemplateStringsWithManyCallAndMemberExpressions.errors.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ tests/cases/conformance/es6/templates/taggedTemplateStringsWithManyCallAndMember
33

44
==== tests/cases/conformance/es6/templates/taggedTemplateStringsWithManyCallAndMemberExpressions.ts (1 errors) ====
55
interface I {
6-
(strs: string[], subs: number[]): I;
6+
(strs: string[], ...subs: number[]): I;
77
member: {
88
new (s: string): {
99
new (n: number): {

tests/baselines/reference/taggedTemplateStringsWithManyCallAndMemberExpressionsES6.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//// [taggedTemplateStringsWithManyCallAndMemberExpressionsES6.ts]
22
interface I {
3-
(strs: string[], subs: number[]): I;
3+
(strs: string[], ...subs: number[]): I;
44
member: {
55
new (s: string): {
66
new (n: number): {

tests/baselines/reference/taggedTemplateStringsWithManyCallAndMemberExpressionsES6.types

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
interface I {
33
>I : I
44

5-
(strs: string[], subs: number[]): I;
5+
(strs: string[], ...subs: number[]): I;
66
>strs : string[]
77
>subs : number[]
88
>I : I
@@ -28,11 +28,11 @@ var f: I;
2828
var x = new new new f `abc${ 0 }def`.member("hello")(42) === true;
2929
>x : boolean
3030
>new new new f `abc${ 0 }def`.member("hello")(42) === true : boolean
31-
>new new new f `abc${ 0 }def`.member("hello")(42) : any
32-
>new new f `abc${ 0 }def`.member("hello")(42) : any
33-
>new f `abc${ 0 }def`.member("hello") : any
34-
>f `abc${ 0 }def`.member : any
31+
>new new new f `abc${ 0 }def`.member("hello")(42) : boolean
32+
>new new f `abc${ 0 }def`.member("hello")(42) : new () => boolean
33+
>new f `abc${ 0 }def`.member("hello") : new (n: number) => new () => boolean
34+
>f `abc${ 0 }def`.member : new (s: string) => new (n: number) => new () => boolean
3535
>f : I
36-
>member : any
36+
>member : new (s: string) => new (n: number) => new () => boolean
3737

3838

0 commit comments

Comments
 (0)