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"

Relaterade artiklar