[英]Typescript source parse: get interface related to certain react class
I want to get props from React class declared in interface related to this class. 我想从与此类相关的接口中声明的React类获取道具。 For example I have this kind of code
例如我有这种代码
interface SomeProps {
text: string;
label?: string;
}
class SomeClass extends React.Component<SomeProps> {
...
}
How can I get props of SomeClass declared in SomeProps using ts compiler api from source file? 如何使用ts编译器api从源文件中获取SomeProps中声明的SomeClass道具?
Sure you can use the compiler API to achieve this. 当然,您可以使用编译器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"], {});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.