https://dev.doctorevidence.com/how-to-write-a-typescript-transform-plugin-fc5308fdd943
This article (https://levelup.gitconnected.com/writing-typescript-custom-ast-transformer-part-1-7585d6916819) shows how to include transform in compile process, using a own compiler wrapper.
at this time (2020) the only way to pass compile time type information to run time (e.g. https://github.com/kimamula/ts-transformer-keys)
learn how tool chain works under the hood
"manual code review -> compile time transformation"
Compiler parse source code into AST (abstract syntax tree)
Transform manipulates AST
Then AST is written to target files ("emitted"), i.e. javascript
AST Viewer: https://ts-ast-viewer.com/#
This is a very useful tool, paste typescript code, get AST and code to generate that tree
import * as ts from ‘typescript’
export default function(/*opts?: Opts*/) {
function visitor(ctx: ts.TransformationContext, sf: ts.SourceFile) {
const visitor: ts.Visitor = (node: ts.Node): ts.VisitResult => {
// here we can check each node and potentially return
// new nodes if we want to leave the node as is, and
// continue searching through child nodes:
return ts.visitEachChild(node, visitor, ctx)
}
return visitor
}
return (ctx: ts.TransformationContext): ts.Transformer => {
return (sf: ts.SourceFile) => ts.visitNode(sf, visitor(ctx, sf))
}
}
const visitor: ts.Visitor = (node: ts.Node): ts.VisitResult => {
if (ts.isCallExpression(node) &&
node.expression.getText(sf) == 'safely') {
// get the argument to safely
const target = node.arguments[0]
// check to make sure it is a property access, like "a.b"
if (ts.isPropertyAccessExpression(target) {
// return a binary expression with a && a.b
return ts.createBinary(
target.expression, // the left hand operand is the object
ts.SyntaxKind.AmpersandAmpersandToken, // the && operator
target) // the right hand operand is the full expression
}
}
// otherwise continue visiting all the nodes
return ts.visitEachChild(node, visitor, ctx)
}
https://github.com/microsoft/TypeScript/issues/14419#issuecomment-298814505
At the moment (2020 July) transformers still cannot be invoked through tsconfig.conf. Have to use programatically.
tsc
replacementCompiler API: https://github.com/Microsoft/TypeScript/wiki/Using-the-Compiler-API
Read this: https://levelup.gitconnected.com/writing-typescript-custom-ast-transformer-part-1-7585d6916819
Use a Visitor to visit each node (see boilerplate)
Screen the nodes to find the one we want to transform.
To manipulate: