Skip to content

Commit 10b240c

Browse files
authored
Allow an infer type node to resolve its own name (#40483)
1 parent 78830f3 commit 10b240c

File tree

5 files changed

+169
-0
lines changed

5 files changed

+169
-0
lines changed

src/compiler/checker.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1954,6 +1954,15 @@ namespace ts {
19541954
}
19551955
}
19561956
break;
1957+
case SyntaxKind.InferType:
1958+
if (meaning & SymbolFlags.TypeParameter) {
1959+
const parameterName = (<InferTypeNode>location).typeParameter.name;
1960+
if (parameterName && name === parameterName.escapedText) {
1961+
result = (<InferTypeNode>location).typeParameter.symbol;
1962+
break loop;
1963+
}
1964+
}
1965+
break;
19571966
}
19581967
if (isSelfReferenceLocation(location)) {
19591968
lastSelfReferenceLocation = location;
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
//// [declarationEmitShadowingInferNotRenamed.ts]
2+
// Any instance type
3+
type Client = string
4+
5+
// Modified instance
6+
type UpdatedClient<C> = C & {foo: number}
7+
8+
export const createClient = <
9+
D extends
10+
| (new (...args: any[]) => Client) // accept class
11+
| Record<string, new (...args: any[]) => Client> // or map of classes
12+
>(
13+
clientDef: D
14+
): D extends new (...args: any[]) => infer C
15+
? UpdatedClient<C> // return instance
16+
: {
17+
[K in keyof D]: D[K] extends new (...args: any[]) => infer C // or map of instances respectively
18+
? UpdatedClient<C>
19+
: never
20+
} => {
21+
return null as any
22+
}
23+
24+
//// [declarationEmitShadowingInferNotRenamed.js]
25+
"use strict";
26+
exports.__esModule = true;
27+
exports.createClient = void 0;
28+
var createClient = function (clientDef) {
29+
return null;
30+
};
31+
exports.createClient = createClient;
32+
33+
34+
//// [declarationEmitShadowingInferNotRenamed.d.ts]
35+
declare type Client = string;
36+
declare type UpdatedClient<C> = C & {
37+
foo: number;
38+
};
39+
export declare const createClient: <D extends Record<string, new (...args: any[]) => Client> | (new (...args: any[]) => Client)>(clientDef: D) => D extends new (...args: any[]) => infer C ? UpdatedClient<C> : { [K in keyof D]: D[K] extends new (...args: any[]) => infer C_1 ? UpdatedClient<C_1> : never; };
40+
export {};
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
=== tests/cases/compiler/declarationEmitShadowingInferNotRenamed.ts ===
2+
// Any instance type
3+
type Client = string
4+
>Client : Symbol(Client, Decl(declarationEmitShadowingInferNotRenamed.ts, 0, 0))
5+
6+
// Modified instance
7+
type UpdatedClient<C> = C & {foo: number}
8+
>UpdatedClient : Symbol(UpdatedClient, Decl(declarationEmitShadowingInferNotRenamed.ts, 1, 20))
9+
>C : Symbol(C, Decl(declarationEmitShadowingInferNotRenamed.ts, 4, 19))
10+
>C : Symbol(C, Decl(declarationEmitShadowingInferNotRenamed.ts, 4, 19))
11+
>foo : Symbol(foo, Decl(declarationEmitShadowingInferNotRenamed.ts, 4, 29))
12+
13+
export const createClient = <
14+
>createClient : Symbol(createClient, Decl(declarationEmitShadowingInferNotRenamed.ts, 6, 12))
15+
16+
D extends
17+
>D : Symbol(D, Decl(declarationEmitShadowingInferNotRenamed.ts, 6, 29))
18+
19+
| (new (...args: any[]) => Client) // accept class
20+
>args : Symbol(args, Decl(declarationEmitShadowingInferNotRenamed.ts, 8, 12))
21+
>Client : Symbol(Client, Decl(declarationEmitShadowingInferNotRenamed.ts, 0, 0))
22+
23+
| Record<string, new (...args: any[]) => Client> // or map of classes
24+
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
25+
>args : Symbol(args, Decl(declarationEmitShadowingInferNotRenamed.ts, 9, 26))
26+
>Client : Symbol(Client, Decl(declarationEmitShadowingInferNotRenamed.ts, 0, 0))
27+
28+
>(
29+
clientDef: D
30+
>clientDef : Symbol(clientDef, Decl(declarationEmitShadowingInferNotRenamed.ts, 10, 2))
31+
>D : Symbol(D, Decl(declarationEmitShadowingInferNotRenamed.ts, 6, 29))
32+
33+
): D extends new (...args: any[]) => infer C
34+
>D : Symbol(D, Decl(declarationEmitShadowingInferNotRenamed.ts, 6, 29))
35+
>args : Symbol(args, Decl(declarationEmitShadowingInferNotRenamed.ts, 12, 18))
36+
>C : Symbol(C, Decl(declarationEmitShadowingInferNotRenamed.ts, 12, 42))
37+
38+
? UpdatedClient<C> // return instance
39+
>UpdatedClient : Symbol(UpdatedClient, Decl(declarationEmitShadowingInferNotRenamed.ts, 1, 20))
40+
>C : Symbol(C, Decl(declarationEmitShadowingInferNotRenamed.ts, 12, 42))
41+
42+
: {
43+
[K in keyof D]: D[K] extends new (...args: any[]) => infer C // or map of instances respectively
44+
>K : Symbol(K, Decl(declarationEmitShadowingInferNotRenamed.ts, 15, 7))
45+
>D : Symbol(D, Decl(declarationEmitShadowingInferNotRenamed.ts, 6, 29))
46+
>D : Symbol(D, Decl(declarationEmitShadowingInferNotRenamed.ts, 6, 29))
47+
>K : Symbol(K, Decl(declarationEmitShadowingInferNotRenamed.ts, 15, 7))
48+
>args : Symbol(args, Decl(declarationEmitShadowingInferNotRenamed.ts, 15, 40))
49+
>C : Symbol(C, Decl(declarationEmitShadowingInferNotRenamed.ts, 15, 64))
50+
51+
? UpdatedClient<C>
52+
>UpdatedClient : Symbol(UpdatedClient, Decl(declarationEmitShadowingInferNotRenamed.ts, 1, 20))
53+
>C : Symbol(C, Decl(declarationEmitShadowingInferNotRenamed.ts, 15, 64))
54+
55+
: never
56+
} => {
57+
return null as any
58+
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
=== tests/cases/compiler/declarationEmitShadowingInferNotRenamed.ts ===
2+
// Any instance type
3+
type Client = string
4+
>Client : string
5+
6+
// Modified instance
7+
type UpdatedClient<C> = C & {foo: number}
8+
>UpdatedClient : UpdatedClient<C>
9+
>foo : number
10+
11+
export const createClient = <
12+
>createClient : <D extends Record<string, new (...args: any[]) => Client> | (new (...args: any[]) => Client)>(clientDef: D) => D extends new (...args: any[]) => infer C ? UpdatedClient<C> : { [K in keyof D]: D[K] extends new (...args: any[]) => infer C ? UpdatedClient<C> : never; }
13+
>< D extends | (new (...args: any[]) => Client) // accept class | Record<string, new (...args: any[]) => Client> // or map of classes>( clientDef: D): D extends new (...args: any[]) => infer C ? UpdatedClient<C> // return instance : { [K in keyof D]: D[K] extends new (...args: any[]) => infer C // or map of instances respectively ? UpdatedClient<C> : never } => { return null as any} : <D extends Record<string, new (...args: any[]) => Client> | (new (...args: any[]) => Client)>(clientDef: D) => D extends new (...args: any[]) => infer C ? UpdatedClient<C> : { [K in keyof D]: D[K] extends new (...args: any[]) => infer C ? UpdatedClient<C> : never; }
14+
15+
D extends
16+
| (new (...args: any[]) => Client) // accept class
17+
>args : any[]
18+
19+
| Record<string, new (...args: any[]) => Client> // or map of classes
20+
>args : any[]
21+
22+
>(
23+
clientDef: D
24+
>clientDef : D
25+
26+
): D extends new (...args: any[]) => infer C
27+
>args : any[]
28+
29+
? UpdatedClient<C> // return instance
30+
: {
31+
[K in keyof D]: D[K] extends new (...args: any[]) => infer C // or map of instances respectively
32+
>args : any[]
33+
34+
? UpdatedClient<C>
35+
: never
36+
} => {
37+
return null as any
38+
>null as any : any
39+
>null : null
40+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// @declaration: true
2+
// Any instance type
3+
type Client = string
4+
5+
// Modified instance
6+
type UpdatedClient<C> = C & {foo: number}
7+
8+
export const createClient = <
9+
D extends
10+
| (new (...args: any[]) => Client) // accept class
11+
| Record<string, new (...args: any[]) => Client> // or map of classes
12+
>(
13+
clientDef: D
14+
): D extends new (...args: any[]) => infer C
15+
? UpdatedClient<C> // return instance
16+
: {
17+
[K in keyof D]: D[K] extends new (...args: any[]) => infer C // or map of instances respectively
18+
? UpdatedClient<C>
19+
: never
20+
} => {
21+
return null as any
22+
}

0 commit comments

Comments
 (0)