API компилятора TypeScript получает тип импортируемых имен - PullRequest
0 голосов
/ 25 мая 2018

Рассмотрим следующую import декларацию.

import { a } from "moduleName"

Как получить объявленный тип a.Например, ClassDeclaration или FunctionDeclration или Namespace, а также имя типа в случае класса или функции?

В приведенном выше примере a равно ImportSpecifier, однакокогда я пытаюсь разрешить его, используя typeChecker.getSymbolAtLocation и typeChecker.getTypeAtLocation, я получаю только Identifier типа any.

1 Ответ

0 голосов
/ 25 мая 2018

Вы можете использовать getTypeAtLocation, чтобы получить тип типа импорта, а затем использовать type.getSymbol().getDeclarations(), чтобы получить символ и объявления.

Для следующих файлов:

// module.ts
export class A {
}

export function F(){    
}

// sample.ts
import { A, F} from './module';

Этот код выведет объявления и полное имя типа для импорта:

import * as ts from "typescript";

function compile(fileNames: string[], options: ts.CompilerOptions): void {
    let program = ts.createProgram(fileNames, options);
    let sample = program.getSourceFile("sample.ts");
    let checker = program.getTypeChecker();

    let list = sample.getChildAt(0) as ts.SyntaxList;
    let importStm = list.getChildAt(0);
    if (ts.isImportDeclaration(importStm)) { // get the declaration 
        let clauses = importStm.importClause;
        let namedImport = clauses.getChildAt(0); // get the named imports
        if (!ts.isNamedImports(namedImport)) return;
        for (let i = 0, n = namedImport.elements.length; i < n; i++) { // Iterate the named imports
            let imp = namedImport.elements[i];
            console.log(`Import: ${imp.getText()}`);
            // Get Type 
            let type = checker.getTypeAtLocation(imp);
            // Full name 
            console.log(`Name: ${checker.getFullyQualifiedName(type.getSymbol())}`);
            // Get the declarations (can be multiple), and print them 
            console.log(`Declarations: `)
            type.getSymbol().getDeclarations().forEach(d => console.log(d.getText()));
        }

    }
}

compile(["module.ts", "sample.ts"], {}); 

Для интерфейсов возникает сложность, возвращаемый тип неизвестен, это сделано намеренно, так как этот комментарийв компиляторе говорит нам, а также предлагает обойти:

// It only makes sense to get the type of a value symbol. If the result of resolving
// the alias is not a value, then it has no type. To get the type associated with a
// type symbol, call getDeclaredTypeOfSymbol.

Так что для интерфейсов нам нужно использовать:

let symbol = checker.getSymbolAtLocation(imp.name)
// Get Type 
let type = checker.getDeclaredTypeOfSymbol(symbol);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...