API TypeScript: bagaimana cara memeriksa bahwa ekspresi panggilan menggunakan tanda tangan dari antarmuka tertentu?


Saya menggunakan API compiler TypeScript untuk menerapkan beberapa transformasi.

Katakan saya memiliki beberapa paket my-pkg yang mengekspor beberapa antarmuka IExample:

interface IExample {
  method1(): void;
}  

Sekarang misalkan saya memiliki implementasi dari IExample:

import {IExample} from "my-pkg";
declare const foo: IExample;
foo.method1();

Bagaimana cara memeriksa bahwa ekspresi foo.method1() terkait dengan IExample.method1?

Ternyata saya bisa mendapatkan tanda tangan panggilan menggunakan signature=TypeChecker.getResolvedSignature(node);
Tapi bagaimana saya bisa pergi ke tanda tangan 'dasar' dan memeriksa bahwa itu berasal dari IExample dari my-pkg?

Saya mencoba menggunakan signature.declaration dan mendapatkan parent-nya (deklarasi kelas atau deklarasi antarmuka) tetapi ini terasa seperti pendekatan yang salah karena dalam kasus ini saya perlu menelusuri semua klausa extends/implements parent untuk memverifikasi bahwa parent mewarisi IExample di suatu tempat.

Jawaban #1

Jika Anda mendapatkan simbol dari ekspresi panggilan (foo.method1), itu seharusnya simbol untuk method1(): void dalam IExample:

const symbol = typeChecker.getSymbolAtLocation(callExpr.expression);

// should output `method1`
console.log(symbol!.escapedName);

// should output `method1(): void`
console.log(symbol!.declarations[0].getText());

Anda perlu menangani symbol yang mungkin undefined dan kemungkinan ada beberapa deklarasi pada simbol tersebut (misalnya, beberapa interface dengan nama yang sama yang digabung melalui penggabungan deklarasi).