TS Internals — Series 2

Preview — 3 of 10 questions

Can this custom transformer be applied using only tsconfig.json and the plain tsc CLI?

javascript
import * as ts from 'typescript';

function removeConsoleLogTransformer(context: ts.TransformationContext) {
  return (sourceFile: ts.SourceFile): ts.SourceFile => {
    function visit(node: ts.Node): ts.Node | undefined {
      if (
        ts.isExpressionStatement(node) &&
        ts.isCallExpression(node.expression) &&
        ts.isPropertyAccessExpression(node.expression.expression) &&
        node.expression.expression.expression.getText() === 'console'
      ) {
        return undefined;
      }
      return ts.visitEachChild(node, visit, context);
    }
    return ts.visitNode(sourceFile, visit) as ts.SourceFile;
  };
}
AYes — tsconfig.json has a transformers array specifically for registering custom AST transformers like this one
BYes, via the plugins array under compilerOptions, exactly like editor language-service plugins
CNo — custom AST transformers of this kind are only supported by Babel, never by the TypeScript compiler itself
DNo — the plain tsc CLI has no built-in mechanism for registering a custom transformer function through tsconfig.json alone; applying one requires either programmatically invoking the TypeScript Compiler API (ts.createProgram with a customTransformers option, or ts.transform directly) from a custom build script, or using a third-party tool (e.g. ts-patch, ttypescript) that patches tsc to add support for exactly this

javascript
{
  "compilerOptions": {
    "sourceMap": true,
    "sourceRoot": "/original-src/",
    "mapRoot": "https://cdn.example.com/maps/"
  }
}
AsourceRoot overrides where a debugger looks for the original source files referenced inside a .js.map file; mapRoot overrides where the debugger looks for the .js.map files themselves — both useful when source files or source maps are deployed or served from a different location than the compiled JavaScript itself (e.g. maps hosted separately, on a CDN, and not shipped alongside production code)
BsourceRoot and mapRoot have no real effect — they're purely cosmetic metadata that every debugger ignores
CsourceRoot and mapRoot control where tsc physically writes the compiled .js files on disk, similar to outDir
DsourceRoot is mandatory whenever sourceMap: true is set — omitting it is a compile-time error

javascript
{ "compilerOptions": { "noEmit": true, "declaration": true } }
ABoth configurations behave identically — neither ever produces any output files
BnoEmit and emitDeclarationOnly are simply two different names for the exact same setting
CnoEmit: true suppresses all file output entirely, including .d.ts declaration files, even with declaration: true set — useful when tsc is run purely for type-checking (e.g. in CI), while a separate tool (Babel, esbuild) handles the actual transpilation; emitDeclarationOnly: true instead specifically suppresses .js output while still emitting .d.ts files — useful for a library build pipeline where a bundler produces the JS, but tsc remains responsible for generating the type declarations
DemitDeclarationOnly suppresses .d.ts output but still emits .js — the reverse of what its name suggests

Sign up free to play

Answer all 10 questions (7 more), see explanations for every answer, and track your score.