我想从与此类相关的接口(interface)中声明的 React 类中获取 Prop 。 例如我有这种代码
interface SomeProps {
text: string;
label?: string;
}
class SomeClass extends React.Component<SomeProps> {
...
}
如何使用源文件中的 ts 编译器 api 获取在 SomeProps 中声明的 SomeClass 的 Prop ?
最佳答案
当然,您可以使用编译器 API 来实现这一点。
// sample.ts
import * as React from 'react'
interface SomeProps {
text: string;
label?: string;
}
class SomeClass extends React.Component<SomeProps> {
}
// getProps.ts
import * as ts from "typescript";
function isReactComponent (baseType: ts.Type) {
if (baseType == null) return false;
let baseTypeSymbol = baseType.getSymbol();
if (baseTypeSymbol == null) return false;
// Base type is named Component
if (baseTypeSymbol.getName() !== "Component") return false;
var declarations = baseTypeSymbol.declarations;
if (declarations == null) return false;
// With the declartion beeing located inside the react module
return declarations.some(r => r.getSourceFile().fileName.indexOf("node_modules/@types/react") !== -1);
}
function compile(fileNames: string[], options: ts.CompilerOptions): void {
let program = ts.createProgram(fileNames, options);
let sample = program.getSourceFile("sample.ts");
if (sample == null) return;
let checker = program.getTypeChecker();
// Get declarations inside the file
let list = sample.getChildAt(0) as ts.SyntaxList;
for (let i = 0, n = list.getChildCount(); i < n; i++) {
let clazz = list.getChildAt(i);
// if the child is a class
if (!ts.isClassDeclaration(clazz)) continue;
// Get the heritage classes of the class
let heritageClauses = clazz.heritageClauses;
if (heritageClauses == null) continue;
// Iterate the heritage clauses
for (const heritageClause of heritageClauses) {
// Only take the extends clauses
if (heritageClause.token !== ts.SyntaxKind.ExtendsKeyword) continue;
// Get the type of the extends
let extendsType = heritageClause.types[0];
// If the base type is React.Component
if (isReactComponent(checker.getTypeFromTypeNode(extendsType))) {
// Get the type argument of the expression
var propType = extendsType.typeArguments![0];
let type = checker.getTypeFromTypeNode(propType);
console.log(`The name of props is ${type.getSymbol()!.getName()}`);
var props = type.getProperties();
for (let prop of props) {
console.log(` Contains prop: ${prop.getName()}`);
}
}
}
}
}
compile(["sample.ts"], {});
关于javascript - typescript 源解析 : get interface related to certain react class,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50795939/