如何使用Typescript编译器从TypeNode替换TypeParaameter

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用Typescript编译器从TypeNode替换TypeParaameter相关的知识,希望对你有一定的参考价值。

我正在处理班级成员

输入:

 class Sample {

    sn<O extends string>(input:{one: O,
     twO : {k : O},three:O[] }) {

    }
}
}

处理中:

methods.map(m => {
        const n = m.name.getText();
        const params = m.parameters
        const pl = params.length;
        let payload = ""
        if (pl === 1) {
            payload = params[0].type!.getText() //{one: O, two : {k : O},three:O[] })
            if (m.typeParameters) { // if typeParams exist i want replace all occurance of TypeReference O with string
                const tp = m.typeParameters[0]
              payload = `{one: string, twO : {k : string},three:string[] })` // i want result like this
            }
        } 
答案

在这种情况下,研究代码的AST结构并在构建解决方案时参考它很有帮助。您可以使用TypeScript AST Viewer分析AST。

Here is what your code looks like

[您可以在此处看到MethodDeclaration具有typeParameters属性,该属性是TypeParameter的数组。它还具有parameters,它是Parameter的数组。

您想做的是用对应的TypeReference parametersO属性替换TypeParameter中指向O的节点的任何后代中出现的任何constraint

您可以采取几种方法。最简单,记录最广泛的方法是使用变压器。

示例代码

以下示例将适用于所有方法。它在TypeReference parameters中的任何位置查找NodeArray节点,并检查是否引用了该方法的TypeParameter之一。如果是,它将用其约束替换该引用。

这比您的问题要宽一些,但是我认为您的实际应用可能更接近于此。如果没有,您应该能够轻松地对其进行修改,以针对特定的方法或参数名称。

希望这会帮助您指出正确的方向

在StackBlitz上尝试代码:https://stackblitz.com/edit/typescript-transformer-example?file=index.ts

import * as ts from 'typescript'
import { Node, SourceFile } from 'typescript'


/* ****************************************************************************************************************** *
 * Code to transform
 * ****************************************************************************************************************** */

const cls = `
class Sample {
  sn<O extends string>(input:{ one: O, twO : {k : O} ,three:O[] }) {
  }
}
`;


/* ****************************************************************************************************************** *
 * Transformer
 * ****************************************************************************************************************** */

const transformer = (ctx: ts.TransformationContext) => (sourceFile: SourceFile): SourceFile => {
    function paramVisitor(baseMethod: ts.MethodDeclaration) {
        return (node: Node): Node => {
            if (ts.isTypeReferenceNode(node)) {
                const typeParam = baseMethod.typeParameters.find(t => t.name.escapedText === (node.typeName as ts.Identifier).escapedText);
                if (typeParam) return typeParam.constraint;
            }

            return ts.visitEachChild(node, paramVisitor(baseMethod), ctx);
        };
    }

    const visit = (node: Node): Node => {
        if (ts.isMethodDeclaration(node))
            return ts.updateMethod(
                node,
                node.decorators,
                node.modifiers,
                node.asteriskToken,
                node.name,
                node.questionToken,
                node.typeParameters,
                ts.visitNodes(node.parameters, paramVisitor(node)),
                node.type,
                node.body
            );

        return ts.visitEachChild(node, visit, ctx);
    };

    return ts.visitNode(sourceFile, visit);
};


/* ****************************************************************************************************************** *
 * Demonstration
 * ****************************************************************************************************************** */

const s = ts.createSourceFile('example.ts', cls, ts.ScriptTarget.ES5);
const { transformed } = ts.transform(s, [ transformer ]);

console.log(ts.createPrinter().printFile(transformed.find(f => f.fileName === 'example.ts')));

推荐阅读:

How to Write a TypeScript Transform (Plugin)

Creating a TypeScript Transformer

推荐工具:

ts-query-对于更多的外科手术方法

ts-morph-可以帮助简化编译器API的工作。

[ts-patch-如果在编译tsc时需要应用转换器

PS

[以后,将标签typescript-compiler-api添加到您的帖子中。这些类型的问题更有可能被该标签回答。

如果您不介意将其添加到您的帖子中以提高知名度,那会对其他人有所帮助!

以上是关于如何使用Typescript编译器从TypeNode替换TypeParaameter的主要内容,如果未能解决你的问题,请参考以下文章

如何让 TypeScript 从 node_modules 捆绑第 3 方库?

TypeScript:当编译增加项目结构的深度时如何从父文件夹导入

Intellij 不断编译 TypeScript(非常慢) - 如何阻止这种行为?

如何使用 CLI 将带有节点模块的 TypeScript Web 应用程序编译成一个 JavaScript 文件? [关闭]

如何使用编译器包含的构建(Vue、Typescript、Webpack)

在文件保存时自动编译 TypeScript 文件