Typescript 反射 - 必需的参数和默认值
Typescript reflection - required parameters & default values
简而言之:有没有办法知道是否需要打字稿参数and/or有默认值?
更长的版本:
假设我有以下文件:
//Foo.ts
class Bar {
foo(required:string,defaultValue:number=0,optional?:boolean) {
...
}
}
我想知道每个参数:
- 名字
- 类型
- 需要吗?
- 它有默认值吗?
我已经成功地使用 method decorators with the TypeScript reflection API to get the types of the parameters, I've used this method 得到了他们的名字,但是到目前为止我还没有找到一种方法来知道一个变量是否是 required and/or有一个默认值。
我知道 typescript 编译器本身可以在 typescript 中使用。所以想知道有没有办法利用编译器的parse tree来查看某个参数是否需要and/or有默认值?
那将如何运作?
如果您想从头开始...
在高层次上,一种方法是:
弄清楚如何使用文件的编译器 api 获取 SourceFile
节点。这本身就需要一些解释。
从那里,使用 api 的 forEachChild
函数遍历文件中的所有节点并找到具有 kind
的节点 SyntaxKind.ClassDeclaration
和 .name 属性 以及文本 Bar
.
然后再次使用 api 的 forEachChild
函数遍历 class 的所有子节点,并得到类型为 SyntaxKind.MethodDeclaration
和 .name 属性 以及文本 foo
.
获取参数需要循环方法节点的parameters
属性.
然后对于每个参数节点,要获取名称,您可以在 .name
属性.
上调用 .getText()
您可以通过以下方式判断参数是否可选:
const parameterDeclaration = parameterNode as ts.ParameterDeclaration;
const isOptional = parameterDeclaration.questionToken != null || parameterDeclaration.initializer != null || parameterDeclaration.dotDotDotToken != null;
或者您可以使用 TypeChecker
的 isOptionalParameter
方法。
要获取其默认表达式,您只需检查 initializer
属性:
propertyDeclaration.initializer;
要获取类型,请使用 TypeChecker
的 getTypeOfSymbolAtLocation
方法并传入节点的符号...这有点复杂,所以我不会'懒得解释了(想想它与联合类型等有何不同)。
不要从头开始...
我已经围绕 TypeScript 编译器创建了一个包装器 api。只需将此代码与 ts-simple-ast (edit: Previously this talked about my old ts-type-info 库一起使用,但 ts-simple-ast 更好):
import { Project } from "ts-morph";
// read more about setup here:
// https://ts-morph.com/setup/adding-source-files
const project = new Project({ tsConfigFilePath: "tsconfig.json" });
const sourceFile = project.getSourceFileOrThrow("src/Foo.ts");
const method = sourceFile.getClassOrThrow("Bar").getInstanceMethodOrThrow("foo");
一旦你有了这个方法,就可以非常简单地从它的参数中获取你需要的所有信息:
console.log(method.getName()); // foo
for (const param of method.getParameters()) {
console.log(param.getName());
console.log(param.getType().getText());
console.log(param.isOptional());
console.log(param.getInitializer() != null);
}
简而言之:有没有办法知道是否需要打字稿参数and/or有默认值?
更长的版本: 假设我有以下文件:
//Foo.ts
class Bar {
foo(required:string,defaultValue:number=0,optional?:boolean) {
...
}
}
我想知道每个参数:
- 名字
- 类型
- 需要吗?
- 它有默认值吗?
我已经成功地使用 method decorators with the TypeScript reflection API to get the types of the parameters, I've used this method 得到了他们的名字,但是到目前为止我还没有找到一种方法来知道一个变量是否是 required and/or有一个默认值。
我知道 typescript 编译器本身可以在 typescript 中使用。所以想知道有没有办法利用编译器的parse tree来查看某个参数是否需要and/or有默认值?
那将如何运作?
如果您想从头开始...
在高层次上,一种方法是:
弄清楚如何使用文件的编译器 api 获取
SourceFile
节点。这本身就需要一些解释。从那里,使用 api 的
forEachChild
函数遍历文件中的所有节点并找到具有kind
的节点SyntaxKind.ClassDeclaration
和 .name 属性 以及文本Bar
.然后再次使用 api 的
forEachChild
函数遍历 class 的所有子节点,并得到类型为SyntaxKind.MethodDeclaration
和 .name 属性 以及文本foo
.获取参数需要循环方法节点的
parameters
属性.然后对于每个参数节点,要获取名称,您可以在
上调用.name
属性..getText()
您可以通过以下方式判断参数是否可选:
const parameterDeclaration = parameterNode as ts.ParameterDeclaration; const isOptional = parameterDeclaration.questionToken != null || parameterDeclaration.initializer != null || parameterDeclaration.dotDotDotToken != null;
或者您可以使用
TypeChecker
的isOptionalParameter
方法。要获取其默认表达式,您只需检查
initializer
属性:propertyDeclaration.initializer;
要获取类型,请使用
TypeChecker
的getTypeOfSymbolAtLocation
方法并传入节点的符号...这有点复杂,所以我不会'懒得解释了(想想它与联合类型等有何不同)。
不要从头开始...
我已经围绕 TypeScript 编译器创建了一个包装器 api。只需将此代码与 ts-simple-ast (edit: Previously this talked about my old ts-type-info 库一起使用,但 ts-simple-ast 更好):
import { Project } from "ts-morph";
// read more about setup here:
// https://ts-morph.com/setup/adding-source-files
const project = new Project({ tsConfigFilePath: "tsconfig.json" });
const sourceFile = project.getSourceFileOrThrow("src/Foo.ts");
const method = sourceFile.getClassOrThrow("Bar").getInstanceMethodOrThrow("foo");
一旦你有了这个方法,就可以非常简单地从它的参数中获取你需要的所有信息:
console.log(method.getName()); // foo
for (const param of method.getParameters()) {
console.log(param.getName());
console.log(param.getType().getText());
console.log(param.isOptional());
console.log(param.getInitializer() != null);
}