javascript - typescript 源解析 : get interface related to certain react class

标签 javascript reactjs typescript

我想从与此类相关的接口(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/

相关文章:

javascript - 使用 .width() 返回未定义

javascript - jQuery Ajax : Old content flicks in before showing the loaded content

javascript - Jquery 平滑滚动使用 Offset.top

javascript - 出现错误 "Objects are not valid as React child"

javascript - 如何记录 JavaScript 对象(从 UML Angular )

typescript - Vue、TypeScript 无法调用组件方法

javascript - IE 中未保留前导空格

reactjs - React - 状态钩图不是函数

javascript - 如何访问 xml 提要上的属性

typescript - 命名函数类型