Если вы просто хотите изменить текст исходного файла для добавления свойства, то это можно сделать следующим образом:
- Получить литеральное выражение объекта из AST (используя https://ts -ast-viewer.com помогает понять, как выглядит AST).
- Используйте
ts.updateObjectLiteral
, чтобы получить новый узел для старого узла с новым свойством. - ПечатьВыделите текст нового узла и измените исходный текст печатным текстом узла.
- Если необходимо, измените код на новый AST или просто используйте измененный текст.
Обратите внимание, что при печати объектаliteral удалит любое пользовательское форматирование, которое у вас было ранее, потому что принтер печатает узлы по-своему.Возможно, вы захотите потом запустить код через более симпатичный или другой форматтер.
Пример:
import * as ts from "typescript";
// parse the AST
const sourceFile = ts.createSourceFile("file.ts", "const a = { foo: 'bar' };",
ts.ScriptTarget.Latest, false);
// get the object literal expression
const objectLiteralExpression = sourceFile.statements.find(ts.isVariableStatement)!
.declarationList.declarations[0].initializer as ts.ObjectLiteralExpression;
// get a transformed node with the new property and print it
const transformedOle = ts.updateObjectLiteral(objectLiteralExpression, [
...objectLiteralExpression.properties,
ts.createPropertyAssignment("can", ts.createStringLiteral("haz"))
]);
const newNodeText = ts.createPrinter()
.printNode(ts.EmitHint.Unspecified, transformedOle, sourceFile);
// get the new source file text and reparse it to a new AST
const oldText = sourceFile.text;
const newText = oldText.substring(0, objectLiteralExpression.getStart(sourceFile, true))
+ newNodeText + oldText.substring(objectLiteralExpression.end);
const newSourceFile = ts.createSourceFile("file.ts", newText, ts.ScriptTarget.Latest, false);
// outputs: `const a = { foo: "bar", can: "haz" };`
console.log(newText);
Если вы хотите сделать это во время излучения, тогда посмотрите на предоставление собственного преобразователя дляProgram#emit(...)
.