如何使用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
parameters
的O
属性替换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 文件? [关闭]