Output:
x.push(2) is Array.push: true
y.push("123") is Array.push: false
module M { | |
interface MyArray<T> { | |
push(value: T): void | |
} | |
let x = [1]; | |
x.push(2); | |
let y: MyArray<string>; | |
y.push("123") | |
} |
import ts = require("typescript"); | |
let program = ts.createProgram(["lib.d.ts", "a.ts"], <ts.CompilerOptions>{ module: ts.ModuleKind.AMD }); | |
let checker = program.getTypeChecker(); | |
processPushCalls(program.getSourceFile("a.ts")); | |
function processPushCalls(n: ts.Node) { | |
if (n.kind === ts.SyntaxKind.CallExpression && | |
(<ts.CallExpression>n).expression.kind === ts.SyntaxKind.PropertyAccessExpression && | |
(<ts.PropertyAccessExpression>(<ts.CallExpression>n).expression).name.text === "push") { | |
let symbol = checker.getSymbolAtLocation((<ts.PropertyAccessExpression>(<ts.CallExpression>n).expression).name); | |
let isArrayPush = | |
checker.getFullyQualifiedName(symbol) === "Array.push" && | |
symbol.valueDeclaration && | |
symbol.valueDeclaration.getSourceFile().fileName === "lib.d.ts"; | |
let text = (<any>ts).getTextOfNode(n); // Undocumented! used in demo purposes only | |
console.log(`${text} is Array.push: ${isArrayPush}`); | |
} | |
ts.forEachChild(n, processPushCalls); | |
} |