Skip to content

Instantly share code, notes, and snippets.

@hkoba
Created August 4, 2021 06:35
Show Gist options
  • Save hkoba/4d7c67afa7233a93078bce62cab744c7 to your computer and use it in GitHub Desktop.
Save hkoba/4d7c67afa7233a93078bce62cab744c7 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ts-node
import ts from 'typescript'
// Stolen and modified from:
// transpileModule in TypeScript/src/services/transpile.ts
// createTypescriptContext in angular-cli/packages/ngtools/webpack/src/transformers/spec_helpers.ts
//
function makeProgram(input: string, transpileOptions: ts.TranspileOptions)
// : ts.CompilerHost
{
const options: ts.CompilerOptions = transpileOptions.compilerOptions ?? {};
options.target ??= ts.ScriptTarget.ES2015;
options.suppressOutputPathCheck = true;
const inputFileName = transpileOptions.fileName ?? "module.ts";
const sourceFile = ts.createSourceFile(inputFileName, input, options.target)
if (transpileOptions.moduleName) {
sourceFile.moduleName = transpileOptions.moduleName
}
let outputText: string | undefined;
let sourceMapText: string | undefined;
let diagnostics: [string, ts.Diagnostic][] = []
const compilerHost = ts.createCompilerHost(options, true)
const origGetSourceFile = compilerHost.getSourceFile
compilerHost.getSourceFile =
(fileName, version) => fileName === inputFileName ? sourceFile
: origGetSourceFile(fileName, version);
compilerHost.writeFile = (name: string, text: string) => {
if (/\.map$/.exec(name)) {
if (sourceMapText != null)
throw new Error(`Multiple sourcemap output`)
sourceMapText = text;
} else {
if (outputText != null)
throw new Error(`Multiple output`)
outputText = text;
}
}
const program = ts.createProgram([inputFileName], options, compilerHost);
program.emit();
if (outputText == null) {
console.error(`Compilation failed`);
}
for (const diag of program.getSyntacticDiagnostics()) {
diagnostics.push(['Syntactic', diag])
}
for (const diag of program.getGlobalDiagnostics()) {
diagnostics.push(['Global', diag])
}
for (const diag of program.getSemanticDiagnostics()) {
diagnostics.push(['Semantic', diag])
}
for (const diag of program.getDeclarationDiagnostics()) {
diagnostics.push(['Declaration', diag])
}
return {program, outputText: outputText ?? '' , sourceMapText, diagnostics};
}
let {outputText, diagnostics} = makeProgram(`let x:number = 'foo'`, {
compilerOptions: {
strict: true,
target: ts.ScriptTarget.ES2015,
module: ts.ModuleKind.ES2015,
},
reportDiagnostics: true
});
console.log(outputText, diagnostics);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment