Consider the following import declaration.
import { a } from "moduleName"
How can I get the declared type of a. For example, ClassDeclaration or FunctionDeclration or Namespace and also the name of the type in the case of a class or function?
In the above example,
a is ImportSpecifier, however when I try to resolve it using typeChecker.getSymbolAtLocation and typeChecker.getTypeAtLocation I only get an Identifier of type any.
You can use getTypeAtLocation to get the type of type of the import, and then use type.getSymbol().getDeclarations() to get the symbol and the declarations.
Given the following files:
// module.ts
export class A {
}
export function F(){
}
// sample.ts
import { A, F} from './module';
This code will output the declarations and the full type name for the imports:
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"], {});
For interfaces there is a complication, the type returned is unknown, this is done intentionally as this comment in the compiler tells us, and it also suggests a work around:
// 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.
So for interfaces we need to use:
let symbol = checker.getSymbolAtLocation(imp.name)
// Get Type
let type = checker.getDeclaredTypeOfSymbol(symbol);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With