abstrakt syntaksträd - Hur får man den härledda typen från ett TypeScript AST?
Jag använder den inbyggda parsern för att generera AST från källkoden:
const ts = require('typescript')
//...
const ast = ts.createSourceFile(filename, fs.readFileSync(filename).toString(), ts.ScriptTarget.ES6, true)
Finns det ett sätt att få den härledda typen av en variabel från AST? Till exempel, i koden nedan är bar av typen IBar. Kompilatorn känner till den typen --- bar.foo() kompilerar inte --- hur kan jag programmässigt få typen?
interface IBar { bar() }
const foo : IBar = //...
export const bar = foo
Svar #1
Kompilatorn vet om den typen---bar.foo() kompileras inte---hur kan jag programmässigt få typen?
AST är inte hela historien för TypeChecking. Du behöver en TypeChecker.
Den enklaste lösningen är att skapa ett program (några dokument https://basarat.gitbooks.io/typescript/content/docs/compiler/program.html) och sedan använda program.getTypeChecker (fler dokument https://basarat.gitbooks.io/typescript/content/docs/compiler/checker.html) 🌹
Svar #2
Så vitt jag kan se gör detta tricket:
// load typechecker for file
const program = ts.createProgram([filename], {});
const typeChecker = program.getTypeChecker()
// now get ast
const ast = ts.createSourceFile(filename, filecontents, ts.ScriptTarget.ES6, true))
// get node under question using ts.forEachChild (not shown here)
const node = // ...
const type = typeChecker.getTypeAtLocation(node);
Den enda konstiga delen är att i en variabeldeklaration måste "node" vara value (även kallad FirstLiteralToken) och inte label (även kallad Identifier) — annars är typen odefinierad. Till exempel, om filinnehållet är const foo=123, kommer det inte att fungera att skicka noden för "foo" till typeChecker#getTypeAtLocation. Du måste skicka noden för "123"
