Profiles·Public

typescript

semver>=4.0.0 <7.0.0postconditions35functions18last verified2026-06-23coverage score90%

Postconditions — what we check

  • readFile · file-not-found
    error
    Whenfile does not exist at the specified path
    ThrowsError with code ENOENT (file not found)
    Required handlingCaller MUST wrap ts.sys.readFile() in a try-catch block to handle file-not-found errors. Uncaught ENOENT errors will crash the application.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • readFile · permission-denied
    error
    Wheninsufficient permissions to read the file
    ThrowsError with code EACCES (permission denied)
    Required handlingCaller MUST wrap ts.sys.readFile() in a try-catch block to handle permission errors. File system permissions can vary across environments.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[2]
  • readFile · encoding-error
    warning
    Whenfile contains invalid encoding or binary data read as text
    ThrowsError or returns corrupted string data
    Required handlingCaller SHOULD validate file contents after reading, especially when reading user-provided or external files. Binary files read as text will produce invalid results.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • readDirectory · directory-not-found
    error
    Whendirectory does not exist at the specified path
    ThrowsError with code ENOENT (directory not found)
    Required handlingCaller MUST wrap ts.sys.readDirectory() in a try-catch block to handle directory-not-found errors. Uncaught ENOENT errors will crash the application.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • readDirectory · permission-denied
    error
    Wheninsufficient permissions to read the directory
    ThrowsError with code EACCES (permission denied)
    Required handlingCaller MUST wrap ts.sys.readDirectory() in a try-catch block to handle permission errors. Directory permissions can vary across environments.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[2]
  • readDirectory · symlink-loop
    warning
    Whendirectory contains circular symbolic links
    ThrowsError with code ELOOP (too many symbolic links)
    Required handlingCaller SHOULD wrap ts.sys.readDirectory() in a try-catch to handle symlink loops, especially when scanning user-provided or external directories.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[2]
  • writeFile · permission-denied
    error
    Wheninsufficient permissions to write to the file or directory
    ThrowsError with code EACCES (permission denied)
    Required handlingCaller MUST wrap ts.sys.writeFile() in a try-catch block to handle permission errors. Write permissions can be restricted in production environments.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[2]
  • writeFile · directory-not-found
    error
    Whenparent directory does not exist
    ThrowsError with code ENOENT (directory not found)
    Required handlingCaller MUST either: 1. Wrap ts.sys.writeFile() in a try-catch and handle ENOENT, OR 2. Create parent directories before writing (e.g., using ts.sys.createDirectory or mkdirp)
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[2]
  • writeFile · disk-full
    warning
    Wheninsufficient disk space
    ThrowsError with code ENOSPC (no space left on device)
    Required handlingCaller SHOULD wrap ts.sys.writeFile() in a try-catch to handle disk-full errors, especially for build tools that may write large files.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[2]
  • writeFile · read-only-filesystem
    warning
    Whenfilesystem is mounted read-only
    ThrowsError with code EROFS (read-only file system)
    Required handlingCaller SHOULD wrap ts.sys.writeFile() in a try-catch to handle read-only filesystem errors.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[2]
  • createProgram · file-not-found
    warning
    Whensource file specified in rootNames does not exist
    ThrowsMay throw Error or return program with diagnostics
    Required handlingCaller SHOULD wrap ts.createProgram() in a try-catch AND check ts.getPreEmitDiagnostics() for file-not-found errors. The API may return a program with errors rather than throwing.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • createProgram · create-program-string-option-throws
    error
    WhenA compiler option that requires an enum value (e.g., target, module, moduleResolution, jsx, lib) is passed as a raw string (e.g., "ES2020") instead of the TypeScript enum value (e.g., ts.ScriptTarget.ES2020). This occurs when tsconfig JSON is passed directly to createProgram without parsing via parseJsonConfigFileContent first.
    ThrowsError: '<optionName> is a string value; tsconfig JSON must be parsed with parseJsonSourceFileConfigFileContent or getParsedCommandLineOfConfigFile before passing to createProgram'
    Required handlingAlways parse tsconfig JSON before passing to createProgram: import * as ts from 'typescript'; import * as path from 'path'; // WRONG — passing raw JSON with string "target" value throws const rawConfig = { compilerOptions: { target: 'ES2020', module: 'CommonJS' } }; ts.createProgram(files, rawConfig.compilerOptions); // THROWS! // CORRECT — parse through parseJsonConfigFileContent first const configPath = ts.findConfigFile('./', ts.sys.fileExists, 'tsconfig.json'); const { config } = ts.readConfigFile(configPath!, ts.sys.readFile); const { options, fileNames } = ts.parseJsonConfigFileContent( config, ts.sys, path.dirname(configPath!) ); const program = ts.createProgram(fileNames, options); // options has enum values Alternatively, use enum values directly: ts.createProgram(files, { target: ts.ScriptTarget.ES2020, // enum value, not string module: ts.ModuleKind.CommonJS, // enum value, not string });
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[3]
  • createProgram · invalid-compiler-options
    warning
    Whencompiler options are invalid or incompatible
    ThrowsMay throw Error or return program with diagnostics
    Required handlingCaller SHOULD validate compiler options before passing to ts.createProgram() or check diagnostics after program creation.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • createProgram · unchecked-diagnostics
    warning
    Whenprogram created successfully but contains compilation errors
    ReturnsProgram object with errors accessible via getPreEmitDiagnostics()
    Required handlingCaller MUST call ts.getPreEmitDiagnostics(program) after creating a program to check for compilation errors. Programs can be created even when source files have errors, but emitting without checking diagnostics is unsafe.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • createCompilerHost · custom-host-file-errors
    warning
    Whencustom getSourceFile implementation encounters file system errors
    ThrowsDepends on custom implementation - may throw or return undefined
    Required handlingWhen implementing custom CompilerHost, the getSourceFile method MUST handle file system errors (ENOENT, EACCES) gracefully. Either wrap fs operations in try-catch and return undefined, or allow errors to propagate with clear messages.
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1]
  • transpileModule · transpile-custom-transformer-throws
    warning
    WhenA custom transformer function (passed via transpileOptions.transformers) throws an unhandled exception during node visitation. Custom transformers run inside program.emit() which does not have a catch-all for transformer errors. Any uncaught exception from a transformer propagates directly to the caller.
    ThrowsThe error thrown by the custom transformer (type depends on transformer implementation)
    Required handlingWrap ts.transpileModule() in a try-catch when using custom transformers: import * as ts from 'typescript'; // WRONG — throws if transformer crashes (e.g., on unexpected AST node) const result = ts.transpileModule(sourceCode, { compilerOptions: { module: ts.ModuleKind.CommonJS }, transformers: { before: [myCustomTransformer] } }); // CORRECT — wrap when using transformers try { const result = ts.transpileModule(sourceCode, { compilerOptions: { module: ts.ModuleKind.CommonJS }, transformers: { before: [myCustomTransformer] } }); return result.outputText; } catch (error) { throw new Error(`Transpilation failed: ${error.message}`); } For transformers that don't crash on valid input, the result.diagnostics array always contains any syntax errors (TypeScript does not type-check during transpileModule).
    costmediumin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[1][4]
  • transpileModule · transpile-diagnostics-not-checked
    warning
    WhenThe caller does not check result.diagnostics after calling transpileModule with reportDiagnostics: true. Syntax errors (not type errors) are captured in diagnostics. If diagnostics are not checked, the caller emits JavaScript from invalid TypeScript and the downstream runtime behavior is unpredictable.
    ReturnsTranspileOutput with non-empty diagnostics array containing syntax error Diagnostics. The outputText may be empty string, partial code, or JS equivalent of erroneous TS.
    Required handlingAlways check result.diagnostics when transpileModule is called with reportDiagnostics: const result = ts.transpileModule(input, { compilerOptions: options, reportDiagnostics: true, }); if (result.diagnostics && result.diagnostics.length > 0) { const errorMessages = result.diagnostics.map(d => ts.flattenDiagnosticMessageText(d.messageText, '\n') ); throw new Error(`Transpilation errors: ${errorMessages.join('; ')}`); } return result.outputText; Note: transpileModule does NOT perform type checking. Only syntax errors appear in diagnostics. For type safety, use createProgram + getSemanticDiagnostics.
    costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[5][4]
  • program.emit · emit-operation-canceled
    warning
    WhenA CancellationToken is passed (via the cancellationToken parameter) and the token's throwIfCancellationRequested() method throws OperationCanceledException during emit. Typically occurs in IDE/LSP contexts where the user triggers a new compilation while one is already running. In batch compilation scenarios, cancellation tokens are not commonly used, so this is primarily a concern for language service integrations.
    ThrowsOperationCanceledException (ts.OperationCanceledException — a class, not extending Error)
    Required handlingWhen using a cancellation token with program.emit(), catch OperationCanceledException: import * as ts from 'typescript'; try { const emitResult = program.emit( undefined, undefined, cancellationToken ); } catch (e) { if (e instanceof ts.OperationCanceledException) { // User cancelled — clean up and retry or return return; } throw e; // Re-throw unexpected errors } Note: OperationCanceledException is NOT a subclass of Error in TypeScript's implementation. Use instanceof ts.OperationCanceledException for detection.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[3][1]
  • program.emit · emit-skipped-not-checked
    error
    WhenThe caller does not check emitResult.emitSkipped after program.emit(). When compilation errors prevent emit (e.g., --noEmitOnError option is set, or declaration emit fails), emitSkipped is true and NO output files were written. Callers who skip this check believe compilation succeeded and proceed to deploy or use the non-existent output.
    ReturnsEmitResult with emitSkipped: true and non-empty diagnostics array. No output files are written to disk (the writeFile callback is not invoked for the output files).
    Required handlingAlways check emitResult.emitSkipped and emitResult.diagnostics after emit: import * as ts from 'typescript'; const emitResult = program.emit(); // Check for pre-emit errors (type errors) const allDiagnostics = ts .getPreEmitDiagnostics(program) .concat(emitResult.diagnostics); if (allDiagnostics.length > 0) { allDiagnostics.forEach(diagnostic => { if (diagnostic.file) { const { line, character } = ts.getLineAndCharacterOfPosition( diagnostic.file, diagnostic.start! ); const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); console.error(`${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`); } else { console.error(ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n')); } }); } process.exit(emitResult.emitSkipped ? 1 : 0);
    costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[5][3]
  • program.getSemanticDiagnostics · get-semantic-diagnostics-canceled
    warning
    WhenA cancellation token is in effect (passed to createProgram or via the compiler host) and throwIfCancellationRequested() fires during the type-checking pass. This is the same cancellation mechanism as program.emit().
    ThrowsOperationCanceledException (ts.OperationCanceledException)
    Required handlingWrap getSemanticDiagnostics in try-catch when operating in cancellable contexts: try { const diagnostics = program.getSemanticDiagnostics(); // process diagnostics... } catch (e) { if (e instanceof ts.OperationCanceledException) { return; // Type-checking was cancelled; retry or abort } throw e; }
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[3][1]
  • program.getSemanticDiagnostics · semantic-diagnostics-not-checked-before-emit
    error
    WhenThe caller calls program.emit() without first checking getSemanticDiagnostics() (or getPreEmitDiagnostics()) for errors. When type errors exist, emit may still proceed (unless noEmitOnError: true), producing JavaScript that encodes the broken TypeScript — typically with type assertions cast away, undefined references, or missing members.
    ReturnsReadonly Diagnostic[] with length > 0. If unchecked, program.emit() may still run and produce malformed or incorrect JavaScript files.
    Required handlingCall getPreEmitDiagnostics (which combines syntactic + semantic) before emitting: const diagnostics = ts.getPreEmitDiagnostics(program); if (diagnostics.length > 0) { // Handle type errors before emitting diagnostics.forEach(d => console.error(ts.flattenDiagnosticMessageText(d.messageText, '\n'))); process.exit(1); } program.emit();
    costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[5][3]
  • readConfigFile · readconfigfile-error-not-checked
    error
    WhenThe caller reads result.config without checking result.error first. When the tsconfig file cannot be read (ENOENT, EACCES, readFile returns undefined) or contains malformed JSON, result.error is set and result.config is {} (empty object). Using {} as compiler options silently disables all project-specific compiler settings.
    Returns{ config: {}, error: Diagnostic } where error.messageText describes the failure. In Node.js, pass ts.sys.readFile as the readFile argument.
    Required handlingAlways check result.error before using result.config: import * as ts from 'typescript'; const configPath = ts.findConfigFile('./', ts.sys.fileExists, 'tsconfig.json'); if (!configPath) { throw new Error('Could not find tsconfig.json'); } const { config, error } = ts.readConfigFile(configPath, ts.sys.readFile); // MUST check error — result.config is {} on failure, not undefined if (error) { const message = ts.flattenDiagnosticMessageText(error.messageText, '\n'); throw new Error(`Failed to read tsconfig.json: ${message}`); } const { options, fileNames, errors: parseErrors } = ts.parseJsonConfigFileContent( config, ts.sys, path.dirname(configPath) ); if (parseErrors.length > 0) { parseErrors.forEach(e => console.error(ts.flattenDiagnosticMessageText(e.messageText, '\n'))); }
    costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[5][6]
  • parseJsonConfigFileContent · parsejson-errors-not-checked
    warning
    WhenThe caller uses result.options and result.fileNames without checking result.errors. When the tsconfig JSON contains invalid option values (e.g., unknown "target" value, conflicting "module" and "moduleResolution" settings, invalid "paths" entries), errors are populated but options may be partial or have default values applied.
    ReturnsParsedCommandLine with non-empty errors[] array. The options object may be partially populated — some valid options are applied while invalid ones are skipped.
    Required handlingAlways check result.errors after parseJsonConfigFileContent: const result = ts.parseJsonConfigFileContent( config, ts.sys, path.dirname(configPath) ); if (result.errors.length > 0) { result.errors.forEach(e => { console.error(ts.flattenDiagnosticMessageText(e.messageText, '\n')); }); throw new Error('tsconfig.json has invalid options'); } // Safe to use result.options and result.fileNames const program = ts.createProgram(result.fileNames, result.options);
    costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[5][6]
  • createSourceFile · createsourcefile-parse-errors-not-checked
    warning
    WhenThe caller does not check sourceFile.parseDiagnostics (or equivalent getSyntacticDiagnostics) for syntax errors after calling createSourceFile. TypeScript's parser uses error recovery to produce an AST even for syntactically invalid code. Downstream tools that transform this AST may produce incorrect output or crash on unexpected node shapes.
    ReturnsSourceFile with non-empty parseDiagnostics array. The AST is partially valid — error-recovery nodes may be present with unexpected types or missing children.
    Required handlingCheck parseDiagnostics before operating on the AST: import * as ts from 'typescript'; const sourceFile = ts.createSourceFile( 'input.ts', sourceText, ts.ScriptTarget.Latest, /*setParentNodes*/ true // Set true if you need node.parent ); // Check for syntax errors before transforming if (sourceFile.parseDiagnostics && sourceFile.parseDiagnostics.length > 0) { const errors = sourceFile.parseDiagnostics.map(d => ts.flattenDiagnosticMessageText(d.messageText, '\n') ); throw new Error(`Syntax errors in input: ${errors.join('; ')}`); } // Safe to traverse or transform sourceFile.statements Note: parseDiagnostics is a TypeScript internal field. Use a program and program.getSyntacticDiagnostics(sourceFile) for the public diagnostic API.
    costlowin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[7][1]
  • LanguageService.getSyntacticDiagnostics · language-service-file-not-found-throws
    error
    WhenThe fileName passed to LanguageService.getSyntacticDiagnostics() is not present in the LanguageServiceHost's getScriptFileNames() return value. Common causes: - A new file was added to the project but the host was not updated - The fileName uses a different path separator (/ vs \) than what the host returns - The fileName is an absolute path but the host returns relative paths (or vice versa) - The file was removed from the project but the caller still references it
    ThrowsError: Could not find source file: '<fileName>' (has error.ProgramFiles listing known files)
    Required handlingValidate that the fileName is registered before calling LanguageService methods: import * as ts from 'typescript'; // WRONG — throws if fileName not in host's file list const diagnostics = languageService.getSyntacticDiagnostics(fileName); // CORRECT — check the host's program first const program = languageService.getProgram(); if (!program || !program.getSourceFile(fileName)) { // File is not in the project — update the host or skip return []; } const diagnostics = languageService.getSyntacticDiagnostics(fileName); The error object has a ProgramFiles property listing all currently registered files — useful for debugging path mismatches.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[8][1]
  • LanguageService.getSemanticDiagnostics · language-service-semantic-file-not-found-throws
    error
    WhenThe fileName passed to LanguageService.getSemanticDiagnostics() is not in the LanguageServiceHost's file list. Same causes as getSyntacticDiagnostics — file not registered, path separator mismatch, or stale reference after file removal.
    ThrowsError: Could not find source file: '<fileName>'
    Required handlingSame pattern as getSyntacticDiagnostics — validate file presence before calling: const program = languageService.getProgram(); if (!program || !program.getSourceFile(fileName)) { return []; } const semanticErrors = languageService.getSemanticDiagnostics(fileName);
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[9][1]
  • getPreEmitDiagnostics · preemit-diagnostics-operation-canceled
    warning
    WhenA cancellation token is provided (third argument) and throwIfCancellationRequested() fires during the semantic analysis pass. This is the same cancellation mechanism as program.getSemanticDiagnostics(). In IDE/LSP integrations, a new edit may cancel an in-progress diagnostic collection.
    ThrowsOperationCanceledException (ts.OperationCanceledException)
    Required handlingWrap in try-catch when passing a cancellation token: try { const allDiagnostics = ts.getPreEmitDiagnostics(program, undefined, cancellationToken); if (allDiagnostics.length > 0) { // handle errors } program.emit(undefined, undefined, cancellationToken); } catch (e) { if (e instanceof ts.OperationCanceledException) { // Retry on next opportunity return; } throw e; }
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[5][3]
  • getPreEmitDiagnostics · preemit-diagnostics-not-called-before-emit
    error
    WhenThe caller calls program.emit() without calling ts.getPreEmitDiagnostics() first. When type errors exist, emit may still succeed (produces JavaScript from broken TypeScript) unless noEmitOnError: true is set. The result is JavaScript that crashes at runtime with undefined references, wrong types, or missing properties.
    ReturnsgetPreEmitDiagnostics returns non-empty Diagnostic[] that was never checked. program.emit() proceeds to write incorrect JavaScript files.
    Required handlingThe canonical TypeScript Compiler API pattern requires checking pre-emit diagnostics: const program = ts.createProgram(fileNames, options); // REQUIRED: Check diagnostics before emit const preEmitDiagnostics = ts.getPreEmitDiagnostics(program); if (preEmitDiagnostics.length > 0) { preEmitDiagnostics.forEach(diagnostic => { if (diagnostic.file) { const { line, character } = ts.getLineAndCharacterOfPosition( diagnostic.file, diagnostic.start! ); console.error( `${diagnostic.file.fileName}(${line + 1},${character + 1}):`, ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n') ); } else { console.error(ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n')); } }); process.exit(1); // Do not emit when there are errors } const emitResult = program.emit(); process.exit(emitResult.emitSkipped ? 1 : 0);
    costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[5][3]
  • transform · transform-custom-transformer-throws
    warning
    WhenA user-supplied TransformerFactory or the visitor it returns throws an uncaught exception while ts.transform() is running. This commonly happens when a transformer assumes a node shape that doesn't match (e.g. expects ts.isCallExpression(node) but a parent visitor returned a different node kind), dereferences node.parent without setParentNodes:true, or calls factory.createX with the wrong argument shape. The transformation loop in transformNodes() has no catch — the exception terminates the call.
    ThrowsWhatever the transformer throws (TypeError, custom Error, etc.)
    Required handlingWrap ts.transform() in try-catch when running user-defined or composed transformers: import * as ts from 'typescript'; // WRONG — visitor crashes mid-traversal and aborts the whole transform const result = ts.transform(sourceFile, [myTransformer], options); // CORRECT — catch and surface which transformer failed try { const result = ts.transform(sourceFile, [myTransformer], options); return result.transformed[0]; } catch (error) { throw new Error( `Transformation failed in ${myTransformer.name}: ${(error as Error).message}` ); } finally { // dispose() is required even on success — see transform-result-not-disposed } For pipelines that chain transformers, wrap each one individually so the failing transformer is identifiable. ts.transform() does not tag the error with the offending TransformerFactory.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[10][5]
  • transform · transform-hooks-set-after-init-throws
    warning
    WhenA transformer attempts to assign context.onSubstituteNode or context.onEmitNode AFTER transformNodes() has flipped state to Initialized (which happens before the visitor loop starts). This is a structural-bug pattern: hooks must be wired up inside the TransformerFactory (which runs while state is still Uninitialized), not inside the returned visitor function (which runs after init).
    ThrowsError: Cannot modify transformation hooks after initialization has completed.
    Required handlingSet substitution/emit hooks in the TransformerFactory body, NOT in the returned visitor: // WRONG — hooks set inside visitor, after init has completed const badTransformer: ts.TransformerFactory<ts.SourceFile> = (context) => { return (sourceFile) => { context.onSubstituteNode = (hint, node) => node; // THROWS return ts.visitNode(sourceFile, () => sourceFile); }; }; // CORRECT — hooks set before the visitor runs const goodTransformer: ts.TransformerFactory<ts.SourceFile> = (context) => { context.onSubstituteNode = (hint, node) => node; context.enableSubstitution(ts.SyntaxKind.Identifier); return (sourceFile) => ts.visitNode(sourceFile, () => sourceFile); };
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[10]
  • transform · transform-result-not-disposed
    warning
    WhenThe caller uses result.transformed but never calls result.dispose(). The TransformationResult retains references to the transformation context and the transformed nodes' emit metadata. In a long-running process (compiler service, language server, build watcher, batch transformer) that runs ts.transform() repeatedly, undisposed results accumulate and drive memory growth proportional to source-file size × transform count.
    ReturnsA TransformationResult whose internal disposeEmitNodes path was never invoked. The Node EmitFlags and SourceMapRange data on each transformed node remain reachable from the GC root path that holds the result.
    Required handlingAlways dispose the result when done — use try/finally so dispose runs even if the consumer of `transformed` throws: import * as ts from 'typescript'; const result = ts.transform(sourceFile, transformers, options); try { const printer = ts.createPrinter(); return printer.printFile(result.transformed[0] as ts.SourceFile); } finally { result.dispose(); } For batch pipelines, dispose after each transform — do not accumulate results across the batch.
    costlowin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[5][10]
  • findConfigFile · findconfigfile-undefined-result-not-checked
    error
    WhenThe caller forwards the return value of ts.findConfigFile() into a downstream function that requires a string (ts.readConfigFile, ts.sys.readFile, path.dirname, fs.readFileSync) without first checking for undefined. The miss case is silent: no diagnostic, no thrown error — just `undefined`. The crash happens at the next call site, usually with a confusing TypeError like "Cannot read properties of undefined" or "path must be of type string".
    Returnsundefined when no tsconfig.json (or the configured name) exists at searchPath or any of its ancestors. Common causes: running from outside the project root, the project has a non-standard tsconfig filename, fileExists callback returns false for a path that does exist (case sensitivity / symlink issues).
    Required handlingAlways check the return value before using it: import * as ts from 'typescript'; const configPath = ts.findConfigFile( searchPath, ts.sys.fileExists, 'tsconfig.json' ); if (!configPath) { throw new Error( `Could not find tsconfig.json starting from ${searchPath}. ` + `Pass an explicit --project flag or run from inside a TypeScript project.` ); } const { config, error } = ts.readConfigFile(configPath, ts.sys.readFile); // ... continue with the readConfigFile contract checks Do not use the non-null assertion operator (configPath!) — it suppresses the TS warning but the runtime TypeError is identical. The check is the contract.
    costlowin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[5][3]
  • getParsedCommandLineOfConfigFile · getparsedcommandline-undefined-not-checked
    error
    WhenThe caller invokes ts.getParsedCommandLineOfConfigFile(...) and uses result.options or result.fileNames without checking that the result itself is non-undefined. The undefined path fires when host.readFile returns undefined, throws (caught by tryReadFile), or the file content is not a string. The caller then crashes on the next property access.
    Returnsundefined when the config file cannot be read. The host.onUnRecoverableConfigFileDiagnostic callback fires with a ts.Diagnostic describing the read failure (ENOENT, EACCES, throw from readFile), but the function still returns void 0 to its caller.
    Required handlingAlways check for undefined AND check result.errors when defined: import * as ts from 'typescript'; const host: ts.ParseConfigFileHost = { ...ts.sys, onUnRecoverableConfigFileDiagnostic: (diagnostic) => { const msg = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'); throw new Error(`tsconfig read failed: ${msg}`); }, }; const parsed = ts.getParsedCommandLineOfConfigFile( configFileName, /*optionsToExtend*/ undefined, host ); if (!parsed) { // onUnRecoverableConfigFileDiagnostic already fired if it was // wired up to throw; this guard catches the case where it just // logged a warning. throw new Error(`Failed to parse ${configFileName}`); } if (parsed.errors.length > 0) { parsed.errors.forEach(e => console.error(ts.flattenDiagnosticMessageText(e.messageText, '\n')) ); throw new Error(`tsconfig has invalid options: ${parsed.errors.length} errors`); } // Safe to use parsed.options and parsed.fileNames const program = ts.createProgram(parsed.fileNames, parsed.options);
    costmediumin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[5][6]
  • getParsedCommandLineOfConfigFile · getparsedcommandline-host-missing-callback
    error
    WhenThe ParseConfigFileHost passed to ts.getParsedCommandLineOfConfigFile() does not define onUnRecoverableConfigFileDiagnostic (or defines it as undefined). When the function hits the read-failure path, calling undefined as a function raises TypeError. A spread of ts.sys does NOT include this method — ts.sys is a System, not a ParseConfigFileHost.
    ThrowsTypeError: host.onUnRecoverableConfigFileDiagnostic is not a function
    Required handlingExplicitly provide onUnRecoverableConfigFileDiagnostic when constructing the host — do not rely on object spread to supply it: // WRONG — ts.sys does not have onUnRecoverableConfigFileDiagnostic const host = { ...ts.sys } as ts.ParseConfigFileHost; ts.getParsedCommandLineOfConfigFile(configFileName, undefined, host); // Crashes with TypeError on any read failure. // CORRECT — explicitly wire the diagnostic callback const host: ts.ParseConfigFileHost = { ...ts.sys, onUnRecoverableConfigFileDiagnostic: (diagnostic) => { throw new Error(ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n')); }, }; The host interface also requires getCurrentDirectory and useCaseSensitiveFileNames, both of which ts.sys provides.
    costlowin prodimmediate exceptionusers seeservice unavailablevisibilityvisible
    Sources[6]
  • convertCompilerOptionsFromJson · convertcompileroptions-errors-not-checked
    warning
    WhenThe caller destructures `{ options }` from the result and passes it to ts.createProgram or persists it to disk without inspecting result.errors. Common failures captured silently in errors[] include: unknown option names (typos like "extendend"), string values for enum fields outside the valid set (target: "ES2050"), wrong-typed values (strict: "true" instead of boolean true), and invalid paths/extends. The returned options object has whatever values WERE valid plus defaults for the invalid ones — compilation proceeds with silently wrong settings.
    Returns{ options: CompilerOptions, errors: Diagnostic[] } where errors may be non-empty. options contains successfully-converted entries; invalid entries are omitted (so missing target → default ES3, missing module → default CommonJS, etc.).
    Required handlingAlways inspect errors and abort on non-empty: import * as ts from 'typescript'; const raw = JSON.parse(fs.readFileSync(configPath, 'utf8')); const { options, errors } = ts.convertCompilerOptionsFromJson( raw.compilerOptions, path.dirname(configPath), configPath ); if (errors.length > 0) { errors.forEach(e => console.error(ts.flattenDiagnosticMessageText(e.messageText, '\n')) ); throw new Error( `Invalid compilerOptions in ${configPath}: ${errors.length} error(s)` ); } // Safe to use options — fully validated const program = ts.createProgram(fileNames, options); For the common case (load + parse tsconfig.json from disk), prefer ts.getParsedCommandLineOfConfigFile, which handles the read + parse + extends-resolution in one call. Reach for convertCompilerOptionsFromJson only when the JSON object is already in memory (e.g. embedded in a parent config schema).
    costlowin prodsilent failureusers seedegraded performancevisibilitysilent
    Sources[5][6]

Sources

Every postcondition cites at least one of these. Numbered to match the footnotes above.

  1. [1]github.com/microsoft/TypeScript-wikihttps://github.com/microsoft/TypeScript-wiki/blob/main/Using-the-Compiler-API.md
  2. [2]nodejs.org/docs/latesthttps://nodejs.org/docs/latest/api/errors.html
  3. [3]github.com/microsoft/TypeScripthttps://github.com/microsoft/TypeScript/blob/main/src/compiler/program.ts
  4. [4]github.com/microsoft/TypeScripthttps://github.com/microsoft/TypeScript/blob/main/src/compiler/transpile.ts
  5. [5]raw.githubusercontent.com/microsoft/TypeScript-wikihttps://raw.githubusercontent.com/microsoft/TypeScript-wiki/main/Using-the-Compiler-API.md
  6. [6]github.com/microsoft/TypeScripthttps://github.com/microsoft/TypeScript/blob/main/src/compiler/commandLineParser.ts
  7. [7]github.com/microsoft/TypeScripthttps://github.com/microsoft/TypeScript/blob/main/src/compiler/parser.ts
  8. [8]github.com/microsoft/TypeScripthttps://github.com/microsoft/TypeScript/blob/main/src/services/services.ts#L752
  9. [9]github.com/microsoft/TypeScripthttps://github.com/microsoft/TypeScript/blob/main/src/services/services.ts
  10. [10]github.com/microsoft/TypeScripthttps://github.com/microsoft/TypeScript/blob/main/src/compiler/transformer.ts
Need a different package?
Request a profile