Skip to content

Instantly share code, notes, and snippets.

@jednano
Created April 8, 2020 00:29
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jednano/8f8ec024f13eb34a90d74c0c5c5118c6 to your computer and use it in GitHub Desktop.
Save jednano/8f8ec024f13eb34a90d74c0c5c5118c6 to your computer and use it in GitHub Desktop.
TypeScript Transformer
import { readFile as _readFile } from 'fs';
import * as ts from 'typescript';
import { promisify } from 'util';
const readFile = promisify(_readFile);
transform('input.ts');
async function transform(filename: string) {
const sourceFile = ts.createSourceFile(
'output.ts',
(await readFile(filename)).toString(),
ts.ScriptTarget.ESNext,
/* setParentNodes */ true
);
const result = ts.transform(sourceFile, [transformer]);
ts.createPrinter().printNode(
ts.EmitHint.Expression,
result.transformed[0],
sourceFile
);
}
/**
* @see https://blog.scottlogic.com/2017/05/02/typescript-compiler-api-revisited.html
*/
function transformer<T extends ts.Node>(context: ts.TransformationContext) {
return (rootNode: T) => ts.visitNode(rootNode, visit);
function visit(node: ts.Node) {
node = ts.visitEachChild(node, visit, context);
if (node.kind === ts.SyntaxKind.BinaryExpression) {
const binary = node as ts.BinaryExpression;
if (
binary.left.kind === ts.SyntaxKind.NumericLiteral &&
binary.right.kind === ts.SyntaxKind.NumericLiteral
) {
const left = binary.left as ts.NumericLiteral;
const leftVal = parseFloat(left.text);
const right = binary.right as ts.NumericLiteral;
const rightVal = parseFloat(right.text);
switch (binary.operatorToken.kind) {
case ts.SyntaxKind.PlusToken:
return ts.createLiteral(leftVal + rightVal);
case ts.SyntaxKind.AsteriskToken:
return ts.createLiteral(leftVal * rightVal);
case ts.SyntaxKind.MinusToken:
return ts.createLiteral(leftVal - rightVal);
}
}
}
return node;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment