Allow an infer type node to resolve its own name (#40483)

This commit is contained in:
Wesley Wigham
2020-09-22 21:21:13 -07:00
committed by GitHub
parent 78830f3be2
commit 10b240cde3
5 changed files with 169 additions and 0 deletions

View File

@@ -1954,6 +1954,15 @@ namespace ts {
}
}
break;
case SyntaxKind.InferType:
if (meaning & SymbolFlags.TypeParameter) {
const parameterName = (<InferTypeNode>location).typeParameter.name;
if (parameterName && name === parameterName.escapedText) {
result = (<InferTypeNode>location).typeParameter.symbol;
break loop;
}
}
break;
}
if (isSelfReferenceLocation(location)) {
lastSelfReferenceLocation = location;

View File

@@ -0,0 +1,40 @@
//// [declarationEmitShadowingInferNotRenamed.ts]
// Any instance type
type Client = string
// Modified instance
type UpdatedClient<C> = C & {foo: number}
export const createClient = <
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
}
//// [declarationEmitShadowingInferNotRenamed.js]
"use strict";
exports.__esModule = true;
exports.createClient = void 0;
var createClient = function (clientDef) {
return null;
};
exports.createClient = createClient;
//// [declarationEmitShadowingInferNotRenamed.d.ts]
declare type Client = string;
declare type UpdatedClient<C> = C & {
foo: number;
};
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; };
export {};

View File

@@ -0,0 +1,58 @@
=== tests/cases/compiler/declarationEmitShadowingInferNotRenamed.ts ===
// Any instance type
type Client = string
>Client : Symbol(Client, Decl(declarationEmitShadowingInferNotRenamed.ts, 0, 0))
// Modified instance
type UpdatedClient<C> = C & {foo: number}
>UpdatedClient : Symbol(UpdatedClient, Decl(declarationEmitShadowingInferNotRenamed.ts, 1, 20))
>C : Symbol(C, Decl(declarationEmitShadowingInferNotRenamed.ts, 4, 19))
>C : Symbol(C, Decl(declarationEmitShadowingInferNotRenamed.ts, 4, 19))
>foo : Symbol(foo, Decl(declarationEmitShadowingInferNotRenamed.ts, 4, 29))
export const createClient = <
>createClient : Symbol(createClient, Decl(declarationEmitShadowingInferNotRenamed.ts, 6, 12))
D extends
>D : Symbol(D, Decl(declarationEmitShadowingInferNotRenamed.ts, 6, 29))
| (new (...args: any[]) => Client) // accept class
>args : Symbol(args, Decl(declarationEmitShadowingInferNotRenamed.ts, 8, 12))
>Client : Symbol(Client, Decl(declarationEmitShadowingInferNotRenamed.ts, 0, 0))
| Record<string, new (...args: any[]) => Client> // or map of classes
>Record : Symbol(Record, Decl(lib.es5.d.ts, --, --))
>args : Symbol(args, Decl(declarationEmitShadowingInferNotRenamed.ts, 9, 26))
>Client : Symbol(Client, Decl(declarationEmitShadowingInferNotRenamed.ts, 0, 0))
>(
clientDef: D
>clientDef : Symbol(clientDef, Decl(declarationEmitShadowingInferNotRenamed.ts, 10, 2))
>D : Symbol(D, Decl(declarationEmitShadowingInferNotRenamed.ts, 6, 29))
): D extends new (...args: any[]) => infer C
>D : Symbol(D, Decl(declarationEmitShadowingInferNotRenamed.ts, 6, 29))
>args : Symbol(args, Decl(declarationEmitShadowingInferNotRenamed.ts, 12, 18))
>C : Symbol(C, Decl(declarationEmitShadowingInferNotRenamed.ts, 12, 42))
? UpdatedClient<C> // return instance
>UpdatedClient : Symbol(UpdatedClient, Decl(declarationEmitShadowingInferNotRenamed.ts, 1, 20))
>C : Symbol(C, Decl(declarationEmitShadowingInferNotRenamed.ts, 12, 42))
: {
[K in keyof D]: D[K] extends new (...args: any[]) => infer C // or map of instances respectively
>K : Symbol(K, Decl(declarationEmitShadowingInferNotRenamed.ts, 15, 7))
>D : Symbol(D, Decl(declarationEmitShadowingInferNotRenamed.ts, 6, 29))
>D : Symbol(D, Decl(declarationEmitShadowingInferNotRenamed.ts, 6, 29))
>K : Symbol(K, Decl(declarationEmitShadowingInferNotRenamed.ts, 15, 7))
>args : Symbol(args, Decl(declarationEmitShadowingInferNotRenamed.ts, 15, 40))
>C : Symbol(C, Decl(declarationEmitShadowingInferNotRenamed.ts, 15, 64))
? UpdatedClient<C>
>UpdatedClient : Symbol(UpdatedClient, Decl(declarationEmitShadowingInferNotRenamed.ts, 1, 20))
>C : Symbol(C, Decl(declarationEmitShadowingInferNotRenamed.ts, 15, 64))
: never
} => {
return null as any
}

View File

@@ -0,0 +1,40 @@
=== tests/cases/compiler/declarationEmitShadowingInferNotRenamed.ts ===
// Any instance type
type Client = string
>Client : string
// Modified instance
type UpdatedClient<C> = C & {foo: number}
>UpdatedClient : UpdatedClient<C>
>foo : number
export const createClient = <
>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; }
>< 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; }
D extends
| (new (...args: any[]) => Client) // accept class
>args : any[]
| Record<string, new (...args: any[]) => Client> // or map of classes
>args : any[]
>(
clientDef: D
>clientDef : D
): D extends new (...args: any[]) => infer C
>args : any[]
? UpdatedClient<C> // return instance
: {
[K in keyof D]: D[K] extends new (...args: any[]) => infer C // or map of instances respectively
>args : any[]
? UpdatedClient<C>
: never
} => {
return null as any
>null as any : any
>null : null
}

View File

@@ -0,0 +1,22 @@
// @declaration: true
// Any instance type
type Client = string
// Modified instance
type UpdatedClient<C> = C & {foo: number}
export const createClient = <
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
}