【问题标题】:Typescript Infer type params with Compiler APITypescript 使用 Compiler API 推断类型参数
【发布时间】:2021-05-12 10:27:03
【问题描述】:

使用此代码 (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 可以从类声明中的方法 test 推断出类 MP = numberR = boolean)的隐式类型参数。

我想用Compiler API 做同样的事情。我有program.typeChecker,我被困在这里。如何获得隐式类型参数?

【问题讨论】:

    标签: typescript typescript-compiler-api


    【解决方案1】:

    extends Test 中的 Test 类型 M 没有隐式类型为 Test&lt;number, boolean&gt;M 类将 test 的声明覆盖为 test(q: number): boolean。如果您在extends TestM 中获得ExpressionWithTypeArguemnts 的类型,它将是Test&lt;unknown, unknown&gt;

    M获取类型

    如果你知道Test 的结构是什么并且你有...

    declare class M extends Test {
        test(q: number): boolean;
    }
    

    ...如果你想找到test的参数类型和返回类型,那么你可以这样做:

    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中找到PR

    如果您有Test,并且想在M 中找到PR,并且您不知道Test 的类型可能是什么样的,那么您不能使用前面描述的方法。

    为此,你必须手动遍历Test的类型,然后以同样的方式遍历M,看看Test中的类型参数在M中使用的是什么类型。这样做有点复杂,而且在这里发布的工作/代码太多。

    基本上,没有简单的方法来构建类型,然后与编译器 API 进行比较。有一些建议可以让这更容易(例如Type Builder API ProposalType Relationship API Proposal)。

    也就是说,一种解决方法是通过ts.createSourceFile 创建一个虚拟文件并在其中编写一些代码(例如您的Sgnsgn 声明)然后使用该文件上的类型检查器来解决类型。

    【讨论】:

    • 有问题的 Sgn 仅供参考,TS 可以推断出什么,我想没有它。
    • 换句话说,你建议获取test方法的类型
    • 如果我使用虚拟文件,我可以找到一种方法将其添加到现有程序中。我必须创建另一个程序吗?
    • 没关系。我发现doc comment A Program is an immutable collection
    猜你喜欢
    • 2016-12-05
    • 2018-12-13
    • 2020-03-11
    • 2019-04-26
    • 1970-01-01
    • 1970-01-01
    • 2019-12-06
    • 2019-05-04
    • 2017-12-30
    相关资源
    最近更新 更多