Custom transformer
- TypeScript kursu
- Uzman
- Ders 7/35
- 4 dk
Kendi transformer'ını yazmayı öğrenirsin.
Custom transformer yazma
Kendi transformer'ını yazarken bir visitor fonksiyonu tanımlarsın. Visitor belirli düğümleri tanır ve onları ts.factory ile üretilen yeni düğümlerle değiştirir. Diğer düğümler için ts.visitEachChild ile alt düğümlere iner.
function visit(node: ts.Node): ts.Node {
if (ts.isStringLiteral(node)) {
return ts.factory.createStringLiteral("X");
}
return ts.visitEachChild(node, visit, context);
}Visitor yeni bir düğüm döndürdüğünde o dal tamamen değiştirilir.
Düğüm değişimi ve visitEachChild
Bir düğümü değiştirmenin iki yolu vardır: tamamen yeni bir düğüm döndürmek veya ts.factory.updateX ile mevcut düğümün alanlarını güncellemek. visitEachChild bir alt düğüm değiştiğinde üst düğümü otomatik olarak yeni kopyasıyla günceller.
// identity için bile visitEachChild önerilir
return ts.visitEachChild(node, visit, context);Uygulama String'leri "X" ile değiştir
const a = 'merhaba'; ve const b = 'dünya'; içeren bir kaynak oluştur. Bir transformer yaz: ts.isStringLiteral ile bulunan her StringLiteral düğümünü ts.factory.createStringLiteral("X") ile değiştir. ts.transform ile uygula ve sonucu Printer ile yazdır.
Başlangıç kodu
import * as ts from "typescript";
// Kaynak: const a = 'merhaba'; const b = 'dünya';
// SourceFile oluştur
// Bir transformer yaz: StringLiteral düğümlerini "X" ile değiştir
// transform ile uygula
// Printer ile sonucu yazdır
// kodunu buraya yazÖrnek çözüm
import ts from "typescript";
const sourceText = `const a = 'merhaba';\nconst b = 'dünya';`;
const sf = ts.createSourceFile("app.ts", sourceText, ts.ScriptTarget.Latest, true);
const transformer: ts.TransformerFactory<ts.SourceFile> = (context) => {
function visit(node: ts.Node): ts.Node {
if (ts.isStringLiteral(node)) {
return ts.factory.createStringLiteral("X");
}
return ts.visitEachChild(node, visit, context);
}
return (node) => ts.visitEachChild(node, visit, context);
};
const result = ts.transform(sf, [transformer]);
const printer = ts.createPrinter();
process.stdout.write(printer.printFile(result.transformed[0] as ts.SourceFile));
result.dispose();Beklenen çıktı
const a = "X"; const b = "X";
Soru ve cevaplar
Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.
1 Custom transformer'da bir düğümü değiştirmek için ne yaparsın?
- program.getTypeChecker çağırırsın
- Düğümün text özelliğini doğrudan değiştirirsin
- Visitor fonksiyonunda yeni bir düğüm döndürürsün Doğru cevap
- console.log ile düğümü yazdırırsın
Açıklama: AST düğümleri değişmezdir; text özelliğini değiştiremezsin. Visitor yeni bir düğüm döndürdüğünde o dal değiştirilir.
2 String literal değiştir
function visit(node: ts.Node): ts.Node {
if (ts.isStringLiteral(node)) {
return ts.factory.____("X");
}
return ts.visitEachChild(node, visit, context);
}
function visit(node: ts.Node): ts.Node {
if (ts.isStringLiteral(node)) {
return ts.factory.createStringLiteral("X");
}
return ts.visitEachChild(node, visit, context);
}
Açıklama: createStringLiteral yeni bir StringLiteral düğümü üretir; createString factory'de yoktur, updateStringLiteral mevcut düğümü günceller (burada yeni düğüm istiyoruz).
3 Custom transformer parçaları
| Kavram | Anlamı |
|---|---|
Visitor fonksiyonu |
Düğümleri tanır ve döndürür |
ts.factory.createStringLiteral |
Yeni string düğüm üretir |
ts.visitEachChild |
Alt düğümleri dönüştürür |
ts.isStringLiteral |
Düğüm türünü sınar |