Skip to content

Commit 1243d1a

Browse files
authored
handle any'd method signature types (ie, from special property declarations) (#23316)
1 parent 0c06f2f commit 1243d1a

7 files changed

+194
-1
lines changed

src/compiler/checker.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19090,6 +19090,9 @@ namespace ts {
1909019090

1909119091
const links = getNodeLinks(node);
1909219092
const type = getTypeOfSymbol(node.symbol);
19093+
if (isTypeAny(type)) {
19094+
return type;
19095+
}
1909319096

1909419097
// Check if function expression is contextually typed and assign parameter types if so.
1909519098
if (!(links.flags & NodeCheckFlags.ContextChecked)) {
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
tests/cases/compiler/app.js(6,7): error TS2322: Type '1' is not assignable to type 'WatchHandler<any>'.
2+
3+
4+
==== tests/cases/compiler/func.ts (0 errors) ====
5+
interface ComponentOptions<V> {
6+
watch: Record<string, WatchHandler<any>>;
7+
}
8+
type WatchHandler<T> = (val: T) => void;
9+
declare function extend(options: ComponentOptions<{}>): void;
10+
export var vextend = extend;
11+
==== tests/cases/compiler/app.js (1 errors) ====
12+
import {vextend} from './func';
13+
// hover on vextend
14+
export var a = vextend({
15+
watch: {
16+
data1(val) {
17+
this.data2 = 1;
18+
~~~~~~~~~~
19+
!!! error TS2322: Type '1' is not assignable to type 'WatchHandler<any>'.
20+
},
21+
data2(val) { },
22+
}
23+
});
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//// [tests/cases/compiler/allowJscheckJsTypeParameterNoCrash.ts] ////
2+
3+
//// [func.ts]
4+
interface ComponentOptions<V> {
5+
watch: Record<string, WatchHandler<any>>;
6+
}
7+
type WatchHandler<T> = (val: T) => void;
8+
declare function extend(options: ComponentOptions<{}>): void;
9+
export var vextend = extend;
10+
//// [app.js]
11+
import {vextend} from './func';
12+
// hover on vextend
13+
export var a = vextend({
14+
watch: {
15+
data1(val) {
16+
this.data2 = 1;
17+
},
18+
data2(val) { },
19+
}
20+
});
21+
22+
//// [func.js]
23+
"use strict";
24+
exports.__esModule = true;
25+
exports.vextend = extend;
26+
//// [app.js]
27+
"use strict";
28+
exports.__esModule = true;
29+
var func_1 = require("./func");
30+
// hover on vextend
31+
exports.a = func_1.vextend({
32+
watch: {
33+
data1: function (val) {
34+
this.data2 = 1;
35+
},
36+
data2: function (val) { }
37+
}
38+
});
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
=== tests/cases/compiler/func.ts ===
2+
interface ComponentOptions<V> {
3+
>ComponentOptions : Symbol(ComponentOptions, Decl(func.ts, 0, 0))
4+
>V : Symbol(V, Decl(func.ts, 0, 27))
5+
6+
watch: Record<string, WatchHandler<any>>;
7+
>watch : Symbol(ComponentOptions.watch, Decl(func.ts, 0, 31))
8+
>Record : Symbol(Record, Decl(lib.d.ts, --, --))
9+
>WatchHandler : Symbol(WatchHandler, Decl(func.ts, 2, 1))
10+
}
11+
type WatchHandler<T> = (val: T) => void;
12+
>WatchHandler : Symbol(WatchHandler, Decl(func.ts, 2, 1))
13+
>T : Symbol(T, Decl(func.ts, 3, 18))
14+
>val : Symbol(val, Decl(func.ts, 3, 24))
15+
>T : Symbol(T, Decl(func.ts, 3, 18))
16+
17+
declare function extend(options: ComponentOptions<{}>): void;
18+
>extend : Symbol(extend, Decl(func.ts, 3, 40))
19+
>options : Symbol(options, Decl(func.ts, 4, 24))
20+
>ComponentOptions : Symbol(ComponentOptions, Decl(func.ts, 0, 0))
21+
22+
export var vextend = extend;
23+
>vextend : Symbol(vextend, Decl(func.ts, 5, 10))
24+
>extend : Symbol(extend, Decl(func.ts, 3, 40))
25+
26+
=== tests/cases/compiler/app.js ===
27+
import {vextend} from './func';
28+
>vextend : Symbol(vextend, Decl(app.js, 0, 8))
29+
30+
// hover on vextend
31+
export var a = vextend({
32+
>a : Symbol(a, Decl(app.js, 2, 10))
33+
>vextend : Symbol(vextend, Decl(app.js, 0, 8))
34+
35+
watch: {
36+
>watch : Symbol(watch, Decl(app.js, 2, 24))
37+
38+
data1(val) {
39+
>data1 : Symbol(data1, Decl(app.js, 3, 10))
40+
>val : Symbol(val, Decl(app.js, 4, 10))
41+
42+
this.data2 = 1;
43+
>this : Symbol(__type, Decl(lib.d.ts, --, --))
44+
>data2 : Symbol(data2, Decl(app.js, 4, 16), Decl(app.js, 6, 6))
45+
46+
},
47+
data2(val) { },
48+
>data2 : Symbol(data2, Decl(app.js, 4, 16), Decl(app.js, 6, 6))
49+
>val : Symbol(val, Decl(app.js, 7, 10))
50+
}
51+
});
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
=== tests/cases/compiler/func.ts ===
2+
interface ComponentOptions<V> {
3+
>ComponentOptions : ComponentOptions<V>
4+
>V : V
5+
6+
watch: Record<string, WatchHandler<any>>;
7+
>watch : Record<string, (val: any) => void>
8+
>Record : Record<K, T>
9+
>WatchHandler : (val: T) => void
10+
}
11+
type WatchHandler<T> = (val: T) => void;
12+
>WatchHandler : (val: T) => void
13+
>T : T
14+
>val : T
15+
>T : T
16+
17+
declare function extend(options: ComponentOptions<{}>): void;
18+
>extend : (options: ComponentOptions<{}>) => void
19+
>options : ComponentOptions<{}>
20+
>ComponentOptions : ComponentOptions<V>
21+
22+
export var vextend = extend;
23+
>vextend : (options: ComponentOptions<{}>) => void
24+
>extend : (options: ComponentOptions<{}>) => void
25+
26+
=== tests/cases/compiler/app.js ===
27+
import {vextend} from './func';
28+
>vextend : (options: ComponentOptions<{}>) => void
29+
30+
// hover on vextend
31+
export var a = vextend({
32+
>a : void
33+
>vextend({ watch: { data1(val) { this.data2 = 1; }, data2(val) { }, }}) : void
34+
>vextend : (options: ComponentOptions<{}>) => void
35+
>{ watch: { data1(val) { this.data2 = 1; }, data2(val) { }, }} : { watch: { data1(val: any): void; }; }
36+
37+
watch: {
38+
>watch : { data1(val: any): void; }
39+
>{ data1(val) { this.data2 = 1; }, data2(val) { }, } : { data1(val: any): void; }
40+
41+
data1(val) {
42+
>data1 : (val: any) => void
43+
>val : any
44+
45+
this.data2 = 1;
46+
>this.data2 = 1 : 1
47+
>this.data2 : (val: any) => void
48+
>this : Record<string, (val: any) => void>
49+
>data2 : (val: any) => void
50+
>1 : 1
51+
52+
},
53+
data2(val) { },
54+
>data2 : any
55+
>val : any
56+
}
57+
});
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// @checkJs: true
2+
// @allowJs: true
3+
// @outDir: ./dist
4+
// @filename: func.ts
5+
interface ComponentOptions<V> {
6+
watch: Record<string, WatchHandler<any>>;
7+
}
8+
type WatchHandler<T> = (val: T) => void;
9+
declare function extend(options: ComponentOptions<{}>): void;
10+
export var vextend = extend;
11+
// @filename: app.js
12+
import {vextend} from './func';
13+
// hover on vextend
14+
export var a = vextend({
15+
watch: {
16+
data1(val) {
17+
this.data2 = 1;
18+
},
19+
data2(val) { },
20+
}
21+
});

0 commit comments

Comments
 (0)