Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 8a0b882

Browse filesBrowse files
authored
Fix contextually typed parameter issues (microsoft#36476)
* Fix multiple issues with contextually typed parameters * Accept new baselines * Fix lint error * Add tests * Address CR feedback * Add fourslash tests
1 parent 140fee9 commit 8a0b882
Copy full SHA for 8a0b882
Expand file treeCollapse file tree

11 files changed

+861
-179
lines changed

‎src/compiler/checker.ts

Copy file name to clipboardExpand all lines: src/compiler/checker.ts
+71-82Lines changed: 71 additions & 82 deletions
Large diffs are not rendered by default.
+63-12Lines changed: 63 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,54 @@
1-
tests/cases/compiler/contextuallyTypedParametersWithInitializers.ts(8,29): error TS7031: Binding element 'foo' implicitly has an 'any' type.
2-
tests/cases/compiler/contextuallyTypedParametersWithInitializers.ts(14,27): error TS7006: Parameter 'foo' implicitly has an 'any' type.
3-
tests/cases/compiler/contextuallyTypedParametersWithInitializers.ts(27,42): error TS7031: Binding element 'foo' implicitly has an 'any' type.
1+
tests/cases/compiler/contextuallyTypedParametersWithInitializers.ts(24,24): error TS7006: Parameter 'x' implicitly has an 'any' type.
2+
tests/cases/compiler/contextuallyTypedParametersWithInitializers.ts(40,5): error TS7006: Parameter 'x' implicitly has an 'any' type.
43

54

6-
==== tests/cases/compiler/contextuallyTypedParametersWithInitializers.ts (3 errors) ====
5+
==== tests/cases/compiler/contextuallyTypedParametersWithInitializers.ts (2 errors) ====
76
declare function id1<T>(input: T): T;
87
declare function id2<T extends (x: any) => any>(input: T): T;
98
declare function id3<T extends (x: { foo: any }) => any>(input: T): T;
109
declare function id4<T extends (x: { foo?: number }) => any>(input: T): T;
1110
declare function id5<T extends (x?: number) => any>(input: T): T;
1211

1312
const f10 = function ({ foo = 42 }) { return foo };
14-
const f11 = id1(function ({ foo = 42 }) { return foo }); // Implicit any error
15-
~~~
16-
!!! error TS7031: Binding element 'foo' implicitly has an 'any' type.
13+
const f11 = id1(function ({ foo = 42 }) { return foo });
1714
const f12 = id2(function ({ foo = 42 }) { return foo });
1815
const f13 = id3(function ({ foo = 42 }) { return foo });
1916
const f14 = id4(function ({ foo = 42 }) { return foo });
2017

2118
const f20 = function (foo = 42) { return foo };
22-
const f21 = id1(function (foo = 42) { return foo }); // Implicit any error
23-
~~~~~~~~
24-
!!! error TS7006: Parameter 'foo' implicitly has an 'any' type.
19+
const f21 = id1(function (foo = 42) { return foo });
2520
const f22 = id2(function (foo = 42) { return foo });
2621
const f25 = id5(function (foo = 42) { return foo });
2722

23+
const f1 = (x = 1) => 0; // number
24+
const f2: any = (x = 1) => 0; // number
25+
const f3: unknown = (x = 1) => 0; // number
26+
const f4: Function = (x = 1) => 0; // number
27+
const f5: (...args: any[]) => any = (x = 1) => 0; // any
28+
const f6: () => any = (x = 1) => 0; // number
29+
const f7: () => any = (x?) => 0; // Implicit any error
30+
~~
31+
!!! error TS7006: Parameter 'x' implicitly has an 'any' type.
32+
const f8: () => any = (...x) => 0; // []
33+
34+
declare function g1<T>(x: T): T;
35+
declare function g2<T extends any>(x: T): T;
36+
declare function g3<T extends unknown>(x: T): T;
37+
declare function g4<T extends Function>(x: T): T;
38+
declare function g5<T extends (...args: any[]) => any>(x: T): T;
39+
declare function g6<T extends () => any>(x: T): T;
40+
41+
g1((x = 1) => 0); // number
42+
g2((x = 1) => 0); // number
43+
g3((x = 1) => 0); // number
44+
g4((x = 1) => 0); // number
45+
g5((x = 1) => 0); // any
46+
g6((x = 1) => 0); // number
47+
g6((x?) => 0); // Implicit any error
48+
~~
49+
!!! error TS7006: Parameter 'x' implicitly has an 'any' type.
50+
g6((...x) => 0); // []
51+
2852
// Repro from #28816
2953

3054
function id<T>(input: T): T { return input }
@@ -35,8 +59,35 @@ tests/cases/compiler/contextuallyTypedParametersWithInitializers.ts(27,42): erro
3559

3660
const newGetFoo = id(getFoo);
3761
const newGetFoo2 = id(function getFoo ({ foo = 42 }) {
38-
~~~
39-
!!! error TS7031: Binding element 'foo' implicitly has an 'any' type.
4062
return foo;
4163
});
64+
65+
// Repro from comment in #30840
66+
67+
declare function memoize<F extends Function>(func: F): F;
68+
69+
function add(x: number, y = 0): number {
70+
return x + y;
71+
}
72+
const memoizedAdd = memoize(add);
73+
74+
const add2 = (x: number, y = 0): number => x + y;
75+
const memoizedAdd2 = memoize(add2);
76+
77+
const memoizedAdd3 = memoize((x: number, y = 0): number => x + y);
78+
79+
// Repro from #36052
80+
81+
declare function execute(script: string | Function): Promise<string>;
82+
83+
export function executeSomething() {
84+
return execute((root: HTMLElement, debug = true) => {
85+
if (debug) {
86+
root.innerHTML = '';
87+
}
88+
});
89+
}
90+
91+
const fz1 = (debug = true) => false;
92+
const fz2: Function = (debug = true) => false;
4293

‎tests/baselines/reference/contextuallyTypedParametersWithInitializers.js

Copy file name to clipboardExpand all lines: tests/baselines/reference/contextuallyTypedParametersWithInitializers.js
+155-34Lines changed: 155 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,41 @@ declare function id4<T extends (x: { foo?: number }) => any>(input: T): T;
66
declare function id5<T extends (x?: number) => any>(input: T): T;
77

88
const f10 = function ({ foo = 42 }) { return foo };
9-
const f11 = id1(function ({ foo = 42 }) { return foo }); // Implicit any error
9+
const f11 = id1(function ({ foo = 42 }) { return foo });
1010
const f12 = id2(function ({ foo = 42 }) { return foo });
1111
const f13 = id3(function ({ foo = 42 }) { return foo });
1212
const f14 = id4(function ({ foo = 42 }) { return foo });
1313

1414
const f20 = function (foo = 42) { return foo };
15-
const f21 = id1(function (foo = 42) { return foo }); // Implicit any error
15+
const f21 = id1(function (foo = 42) { return foo });
1616
const f22 = id2(function (foo = 42) { return foo });
1717
const f25 = id5(function (foo = 42) { return foo });
1818

19+
const f1 = (x = 1) => 0; // number
20+
const f2: any = (x = 1) => 0; // number
21+
const f3: unknown = (x = 1) => 0; // number
22+
const f4: Function = (x = 1) => 0; // number
23+
const f5: (...args: any[]) => any = (x = 1) => 0; // any
24+
const f6: () => any = (x = 1) => 0; // number
25+
const f7: () => any = (x?) => 0; // Implicit any error
26+
const f8: () => any = (...x) => 0; // []
27+
28+
declare function g1<T>(x: T): T;
29+
declare function g2<T extends any>(x: T): T;
30+
declare function g3<T extends unknown>(x: T): T;
31+
declare function g4<T extends Function>(x: T): T;
32+
declare function g5<T extends (...args: any[]) => any>(x: T): T;
33+
declare function g6<T extends () => any>(x: T): T;
34+
35+
g1((x = 1) => 0); // number
36+
g2((x = 1) => 0); // number
37+
g3((x = 1) => 0); // number
38+
g4((x = 1) => 0); // number
39+
g5((x = 1) => 0); // any
40+
g6((x = 1) => 0); // number
41+
g6((x?) => 0); // Implicit any error
42+
g6((...x) => 0); // []
43+
1944
// Repro from #28816
2045

2146
function id<T>(input: T): T { return input }
@@ -28,18 +53,48 @@ const newGetFoo = id(getFoo);
2853
const newGetFoo2 = id(function getFoo ({ foo = 42 }) {
2954
return foo;
3055
});
56+
57+
// Repro from comment in #30840
58+
59+
declare function memoize<F extends Function>(func: F): F;
60+
61+
function add(x: number, y = 0): number {
62+
return x + y;
63+
}
64+
const memoizedAdd = memoize(add);
65+
66+
const add2 = (x: number, y = 0): number => x + y;
67+
const memoizedAdd2 = memoize(add2);
68+
69+
const memoizedAdd3 = memoize((x: number, y = 0): number => x + y);
70+
71+
// Repro from #36052
72+
73+
declare function execute(script: string | Function): Promise<string>;
74+
75+
export function executeSomething() {
76+
return execute((root: HTMLElement, debug = true) => {
77+
if (debug) {
78+
root.innerHTML = '';
79+
}
80+
});
81+
}
82+
83+
const fz1 = (debug = true) => false;
84+
const fz2: Function = (debug = true) => false;
3185

3286

3387
//// [contextuallyTypedParametersWithInitializers.js]
3488
"use strict";
89+
exports.__esModule = true;
3590
var f10 = function (_a) {
3691
var _b = _a.foo, foo = _b === void 0 ? 42 : _b;
3792
return foo;
3893
};
3994
var f11 = id1(function (_a) {
4095
var _b = _a.foo, foo = _b === void 0 ? 42 : _b;
4196
return foo;
42-
}); // Implicit any error
97+
});
4398
var f12 = id2(function (_a) {
4499
var _b = _a.foo, foo = _b === void 0 ? 42 : _b;
45100
return foo;
@@ -59,7 +114,7 @@ var f20 = function (foo) {
59114
var f21 = id1(function (foo) {
60115
if (foo === void 0) { foo = 42; }
61116
return foo;
62-
}); // Implicit any error
117+
});
63118
var f22 = id2(function (foo) {
64119
if (foo === void 0) { foo = 42; }
65120
return foo;
@@ -68,6 +123,70 @@ var f25 = id5(function (foo) {
68123
if (foo === void 0) { foo = 42; }
69124
return foo;
70125
});
126+
var f1 = function (x) {
127+
if (x === void 0) { x = 1; }
128+
return 0;
129+
}; // number
130+
var f2 = function (x) {
131+
if (x === void 0) { x = 1; }
132+
return 0;
133+
}; // number
134+
var f3 = function (x) {
135+
if (x === void 0) { x = 1; }
136+
return 0;
137+
}; // number
138+
var f4 = function (x) {
139+
if (x === void 0) { x = 1; }
140+
return 0;
141+
}; // number
142+
var f5 = function (x) {
143+
if (x === void 0) { x = 1; }
144+
return 0;
145+
}; // any
146+
var f6 = function (x) {
147+
if (x === void 0) { x = 1; }
148+
return 0;
149+
}; // number
150+
var f7 = function (x) { return 0; }; // Implicit any error
151+
var f8 = function () {
152+
var x = [];
153+
for (var _i = 0; _i < arguments.length; _i++) {
154+
x[_i] = arguments[_i];
155+
}
156+
return 0;
157+
}; // []
158+
g1(function (x) {
159+
if (x === void 0) { x = 1; }
160+
return 0;
161+
}); // number
162+
g2(function (x) {
163+
if (x === void 0) { x = 1; }
164+
return 0;
165+
}); // number
166+
g3(function (x) {
167+
if (x === void 0) { x = 1; }
168+
return 0;
169+
}); // number
170+
g4(function (x) {
171+
if (x === void 0) { x = 1; }
172+
return 0;
173+
}); // number
174+
g5(function (x) {
175+
if (x === void 0) { x = 1; }
176+
return 0;
177+
}); // any
178+
g6(function (x) {
179+
if (x === void 0) { x = 1; }
180+
return 0;
181+
}); // number
182+
g6(function (x) { return 0; }); // Implicit any error
183+
g6(function () {
184+
var x = [];
185+
for (var _i = 0; _i < arguments.length; _i++) {
186+
x[_i] = arguments[_i];
187+
}
188+
return 0;
189+
}); // []
71190
// Repro from #28816
72191
function id(input) { return input; }
73192
function getFoo(_a) {
@@ -79,36 +198,38 @@ var newGetFoo2 = id(function getFoo(_a) {
79198
var _b = _a.foo, foo = _b === void 0 ? 42 : _b;
80199
return foo;
81200
});
201+
function add(x, y) {
202+
if (y === void 0) { y = 0; }
203+
return x + y;
204+
}
205+
var memoizedAdd = memoize(add);
206+
var add2 = function (x, y) {
207+
if (y === void 0) { y = 0; }
208+
return x + y;
209+
};
210+
var memoizedAdd2 = memoize(add2);
211+
var memoizedAdd3 = memoize(function (x, y) {
212+
if (y === void 0) { y = 0; }
213+
return x + y;
214+
});
215+
function executeSomething() {
216+
return execute(function (root, debug) {
217+
if (debug === void 0) { debug = true; }
218+
if (debug) {
219+
root.innerHTML = '';
220+
}
221+
});
222+
}
223+
exports.executeSomething = executeSomething;
224+
var fz1 = function (debug) {
225+
if (debug === void 0) { debug = true; }
226+
return false;
227+
};
228+
var fz2 = function (debug) {
229+
if (debug === void 0) { debug = true; }
230+
return false;
231+
};
82232

83233

84234
//// [contextuallyTypedParametersWithInitializers.d.ts]
85-
declare function id1<T>(input: T): T;
86-
declare function id2<T extends (x: any) => any>(input: T): T;
87-
declare function id3<T extends (x: {
88-
foo: any;
89-
}) => any>(input: T): T;
90-
declare function id4<T extends (x: {
91-
foo?: number;
92-
}) => any>(input: T): T;
93-
declare function id5<T extends (x?: number) => any>(input: T): T;
94-
declare const f10: ({ foo }: {
95-
foo?: number | undefined;
96-
}) => number;
97-
declare const f11: ({ foo }: any) => any;
98-
declare const f12: ({ foo }: any) => any;
99-
declare const f13: ({ foo }: {
100-
foo: any;
101-
}) => any;
102-
declare const f14: ({ foo }: {
103-
foo?: number | undefined;
104-
}) => number;
105-
declare const f20: (foo?: number) => number;
106-
declare const f21: (foo?: any) => any;
107-
declare const f22: (foo?: any) => any;
108-
declare const f25: (foo?: number | undefined) => number;
109-
declare function id<T>(input: T): T;
110-
declare function getFoo({ foo }: {
111-
foo?: number | undefined;
112-
}): number;
113-
declare const newGetFoo: typeof getFoo;
114-
declare const newGetFoo2: ({ foo }: any) => any;
235+
export declare function executeSomething(): Promise<string>;

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.