TypeChecker
- TypeScript course
- Expert
- Lesson 2/35
- 4 min
Learn symbol and type resolution with TypeChecker.
What is the TypeChecker?
The TypeChecker is the symbol and type resolver produced by the Program. You obtain it with program.getTypeChecker(). For a node, you fetch its symbol with getSymbolAtLocation and its type with getTypeAtLocation.
const program = ts.createProgram(["app.ts"], {}, host);
const checker = program.getTypeChecker();
const sym = checker.getSymbolAtLocation(node);
const type = checker.getTypeAtLocation(node);Without the TypeChecker the AST is pure syntax — it has no meaning.
Symbol and Type
A Symbol represents a declaration — a variable, function or class. symbol.getName() returns the declaration's name. A Type carries type information; for a human-readable form you use checker.typeToString(type).
const sym = checker.getSymbolAtLocation(id);
console.log(sym?.getName()); // "greeting"
const t = checker.getTypeAtLocation(id);
console.log(checker.typeToString(t)); // "string"Practice Resolve the symbol and print its name
Let the in-memory app.ts source be let greeting = 'merhaba';. Define a CompilerHost, build the program with noLib: true. Obtain the TypeChecker, resolve the symbol of the greeting identifier with getSymbolAtLocation and print its name with getName().
Starter code
import * as ts from "typescript";
// Kaynak: let greeting = 'merhaba';
// host'u tanımla (noLib: true ile)
// TypeChecker al
// greeting tanımlayıcısını bul, sembolünü çöz ve adını yazdır
// kodunu buraya yazSample solution
import ts from "typescript";
const fileName = "app.ts";
const sourceText = "let greeting = 'merhaba';";
const host: ts.CompilerHost = {
fileExists: (n) => n === fileName,
readFile: (n) => (n === fileName ? sourceText : undefined),
getSourceFile: (n, lang) =>
n === fileName ? ts.createSourceFile(n, sourceText, lang, true) : undefined,
writeFile: () => {},
getDefaultLibFileName: () => "lib.d.ts",
useCaseSensitiveFileNames: () => true,
getCanonicalFileName: (n) => n,
getCurrentDirectory: () => "",
getNewLine: () => "\n",
};
const program = ts.createProgram([fileName], { noLib: true }, host);
const checker = program.getTypeChecker();
const sf = program.getSourceFile(fileName)!;
const stmt = sf.statements[0] as ts.VariableStatement;
const id = stmt.declarationList.declarations[0].name as ts.Identifier;
const sym = checker.getSymbolAtLocation(id);
console.log(sym?.getName());Expected output
greeting
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 How is the TypeChecker obtained?
- program.getChecker()
- checker.from(program)
- ts.createChecker(program)
- program.getTypeChecker() Correct answer
Explanation: The TypeChecker is obtained via program.getTypeChecker(); it returns the symbol and type resolver. The other names do not exist on Program.
2 Symbol's name
const checker = program.getTypeChecker();
const decl = (sf.statements[0] as ts.VariableStatement).declarationList.declarations[0];
const sym = checker.getSymbolAtLocation(decl.name);
console.log(sym?.____());
const checker = program.getTypeChecker();
const decl = (sf.statements[0] as ts.VariableStatement).declarationList.declarations[0];
const sym = checker.getSymbolAtLocation(decl.name);
console.log(sym?.getName());
Explanation: Symbol.getName() returns the declaration name of the symbol; getType and getId do not exist on Symbol and toString gives the default object representation.
3 TypeChecker parts
| Term | Meaning |
|---|---|
program.getTypeChecker() |
Returns the TypeChecker |
getSymbolAtLocation(node) |
Returns Symbol | undefined |
getTypeAtLocation(node) |
Returns a Type |
symbol.getName() |
Gives the declaration's name |