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