Typescript 使用编译器推断类型参数 API
Typescript Infer type params with Compiler API
使用此代码 (playground):
declare class Test<P = unknown, R = unknown> {
test(p: P): R;
}
declare class M extends Test {
test(q: number): boolean;
}
// these lines are not in real code. This is an example of what TS
// could infer from my code and what I would like to find using Compiler API
type Sgn<M> = M extends Test<infer P, infer R> ? [P, R] : never;
type sgn = Sgn<M>; // [number, boolean]
typescript 可以从 class 声明中的方法 test
推断出 class M
(P = number
、R = boolean
)的隐式类型参数。
我想用 Compiler API 做同样的事情。我有 program.typeChecker
,我被困在这里。我怎样才能获得隐式类型参数?
M
的 extends Test
中的类型 Test
未隐式类型化为 Test<number, boolean>
。 class M
将 test
的声明覆盖为 test(q: number): boolean
。如果您在 M
的 extends Test
中得到 ExpressionWithTypeArguemnts
的类型,它将是 Test<unknown, unknown>
.
从 M
获取类型
如果你知道 Test
的结构是什么并且你有...
declare class M extends Test {
test(q: number): boolean;
}
...而你想找到参数的类型和test
的return类型,那么你可以这样做:
const mDecl = sourceFile.statements.find(child =>
ts.isClassDeclaration(child) && child.name?.escapedText === "M"
)! as ts.ClassDeclaration;
const testMethod = mDecl.members.find(member =>
ts.isMethodDeclaration(member)
&& ts.isIdentifier(member.name)
&& member.name.escapedText === "test"
)! as ts.MethodDeclaration;
// number type
typeChecker.getTypeAtLocation(testMethod.parameters[0]);
// boolean type
typeChecker.getReturnTypeOfSignature(typeChecker.getSignatureFromDeclaration(testMethod));
给定 Test
,在 M
中找到 P
和 R
如果您有 Test
并且想在 M
中查找 P
和 R
并且您不知道 Test
的类型可能长得像,那你就不能用前面介绍的方法了
要做到这一点,就得手动遍历Test
的类型,然后用同样的方法遍历M
,看看Test
中的类型参数用的是什么类型在 M
。这样做有点复杂,这里 work/code 到 post 太多了。
基本上,没有简单的方法来构建类型然后与编译器进行比较 API。有一些建议可以使这更容易(例如 Type Builder API Proposal and Type Relationship API Proposal)。
就是说,解决它的一种方法是通过 ts.createSourceFile
创建一个虚拟文件并在其中编写一些代码(例如您的 Sgn
和 sgn
声明)然后使用该文件的类型检查器以解析类型。
使用此代码 (playground):
declare class Test<P = unknown, R = unknown> {
test(p: P): R;
}
declare class M extends Test {
test(q: number): boolean;
}
// these lines are not in real code. This is an example of what TS
// could infer from my code and what I would like to find using Compiler API
type Sgn<M> = M extends Test<infer P, infer R> ? [P, R] : never;
type sgn = Sgn<M>; // [number, boolean]
typescript 可以从 class 声明中的方法 test
推断出 class M
(P = number
、R = boolean
)的隐式类型参数。
我想用 Compiler API 做同样的事情。我有 program.typeChecker
,我被困在这里。我怎样才能获得隐式类型参数?
M
的 extends Test
中的类型 Test
未隐式类型化为 Test<number, boolean>
。 class M
将 test
的声明覆盖为 test(q: number): boolean
。如果您在 M
的 extends Test
中得到 ExpressionWithTypeArguemnts
的类型,它将是 Test<unknown, unknown>
.
从 M
如果你知道 Test
的结构是什么并且你有...
declare class M extends Test {
test(q: number): boolean;
}
...而你想找到参数的类型和test
的return类型,那么你可以这样做:
const mDecl = sourceFile.statements.find(child =>
ts.isClassDeclaration(child) && child.name?.escapedText === "M"
)! as ts.ClassDeclaration;
const testMethod = mDecl.members.find(member =>
ts.isMethodDeclaration(member)
&& ts.isIdentifier(member.name)
&& member.name.escapedText === "test"
)! as ts.MethodDeclaration;
// number type
typeChecker.getTypeAtLocation(testMethod.parameters[0]);
// boolean type
typeChecker.getReturnTypeOfSignature(typeChecker.getSignatureFromDeclaration(testMethod));
给定 Test
,在 M
P
和 R
如果您有 Test
并且想在 M
中查找 P
和 R
并且您不知道 Test
的类型可能长得像,那你就不能用前面介绍的方法了
要做到这一点,就得手动遍历Test
的类型,然后用同样的方法遍历M
,看看Test
中的类型参数用的是什么类型在 M
。这样做有点复杂,这里 work/code 到 post 太多了。
基本上,没有简单的方法来构建类型然后与编译器进行比较 API。有一些建议可以使这更容易(例如 Type Builder API Proposal and Type Relationship API Proposal)。
就是说,解决它的一种方法是通过 ts.createSourceFile
创建一个虚拟文件并在其中编写一些代码(例如您的 Sgn
和 sgn
声明)然后使用该文件的类型检查器以解析类型。