简体   繁体   English

Typescript源解析:获取与某些React类相关的接口

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM