Skip to main content

Overview

The Program interface is the central component of the TypeScript Compiler API. It represents an immutable collection of source files and compiler options that form a compilation unit.

Creating a Program

ts.createProgram()

Creates a new Program instance.
createProgramOptions
CreateProgramOptions
Options object for creating the program
rootNames
readonly string[]
required
Array of root file names to include in the program
options
CompilerOptions
required
Compiler options for the program
host
CompilerHost
Custom compiler host for file system operations
oldProgram
Program
Previous program instance for incremental compilation
configFileParsingDiagnostics
readonly Diagnostic[]
Diagnostics from parsing the config file
Alternative Signature:
function createProgram(
  rootNames: readonly string[],
  options: CompilerOptions,
  host?: CompilerHost,
  oldProgram?: Program,
  configFileParsingDiagnostics?: readonly Diagnostic[]
): Program

Example

import * as ts from 'typescript';

// Using CreateProgramOptions
const program = ts.createProgram({
  rootNames: ['./src/index.ts', './src/utils.ts'],
  options: {
    target: ts.ScriptTarget.ES2020,
    module: ts.ModuleKind.ESNext,
    strict: true,
    esModuleInterop: true,
    skipLibCheck: true,
    declaration: true,
    outDir: './dist'
  }
});

// Using individual parameters
const program2 = ts.createProgram(
  ['./src/index.ts'],
  { target: ts.ScriptTarget.ES2020 }
);

Program Interface Methods

Source File Methods

getSourceFiles()

Returns all source files in the program.
return
readonly SourceFile[]
Array of all source files in the program
const sourceFiles = program.getSourceFiles();
for (const sourceFile of sourceFiles) {
  console.log(sourceFile.fileName);
}

getRootFileNames()

Returns the list of root file names passed to createProgram.
return
readonly string[]
Array of root file names
const rootFiles = program.getRootFileNames();
console.log('Root files:', rootFiles);

getSourceFile(fileName: string)

Returns a specific source file by name.
fileName
string
required
The name of the source file to retrieve
return
SourceFile | undefined
The source file, or undefined if not found
const sourceFile = program.getSourceFile('./src/index.ts');
if (sourceFile) {
  console.log(`Found: ${sourceFile.fileName}`);
}

Type Checking

getTypeChecker()

Returns a type checker that can be used to perform semantic analysis.
return
TypeChecker
A TypeChecker instance for semantic analysis
const typeChecker = program.getTypeChecker();

// Use the type checker
const sourceFile = program.getSourceFile('./src/index.ts');
if (sourceFile) {
  ts.forEachChild(sourceFile, (node) => {
    if (ts.isIdentifier(node)) {
      const symbol = typeChecker.getSymbolAtLocation(node);
      if (symbol) {
        const type = typeChecker.getTypeOfSymbolAtLocation(symbol, node);
        console.log(`${symbol.name}: ${typeChecker.typeToString(type)}`);
      }
    }
  });
}

Diagnostics

The Program provides several methods for retrieving compilation diagnostics.

getSyntacticDiagnostics()

Returns syntax errors for a source file or all files.
sourceFile
SourceFile
Optional source file to check. If not provided, checks all files.
cancellationToken
CancellationToken
Optional token to cancel the operation
return
readonly DiagnosticWithLocation[]
Array of syntax diagnostics
const syntaxDiagnostics = program.getSyntacticDiagnostics();
if (syntaxDiagnostics.length > 0) {
  console.log('Syntax errors found:');
  syntaxDiagnostics.forEach(diagnostic => {
    const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
    const { line, character } = diagnostic.file!
      .getLineAndCharacterOfPosition(diagnostic.start!);
    console.log(`  ${diagnostic.file!.fileName} (${line + 1},${character + 1}): ${message}`);
  });
}

getSemanticDiagnostics()

Returns semantic/type errors for a source file or all files.
sourceFile
SourceFile
Optional source file to check
cancellationToken
CancellationToken
Optional cancellation token
return
readonly Diagnostic[]
Array of semantic diagnostics
const semanticDiagnostics = program.getSemanticDiagnostics();
if (semanticDiagnostics.length > 0) {
  console.log('Type errors found:');
  semanticDiagnostics.forEach(diagnostic => {
    const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
    console.log(`  ${message}`);
  });
}

getDeclarationDiagnostics()

Returns errors related to declaration file generation.
return
readonly DiagnosticWithLocation[]
Array of declaration diagnostics
const declarationDiagnostics = program.getDeclarationDiagnostics();

getOptionsDiagnostics()

Returns diagnostics related to compiler options.
return
readonly Diagnostic[]
Array of option diagnostics
const optionDiagnostics = program.getOptionsDiagnostics();

getGlobalDiagnostics()

Returns global diagnostics not associated with any specific file.
return
readonly Diagnostic[]
Array of global diagnostics
const globalDiagnostics = program.getGlobalDiagnostics();

getConfigFileParsingDiagnostics()

Returns diagnostics from parsing the tsconfig.json file.
return
readonly Diagnostic[]
Array of config file diagnostics
const configDiagnostics = program.getConfigFileParsingDiagnostics();

Emitting Output

emit()

Emits JavaScript and declaration files for the program.
targetSourceFile
SourceFile
Optional specific file to emit. If not provided, emits all files.
writeFile
WriteFileCallback
Optional custom write callback
cancellationToken
CancellationToken
Optional cancellation token
emitOnlyDtsFiles
boolean
If true, only emits declaration files
customTransformers
CustomTransformers
Optional custom AST transformers
return
EmitResult
Object containing emit results and diagnostics
emitSkipped
boolean
Whether emit was skipped
diagnostics
readonly Diagnostic[]
Diagnostics from the emit process
// Emit all files
const emitResult = program.emit();
if (emitResult.emitSkipped) {
  console.log('Emit was skipped');
} else {
  console.log('Emit successful');
}

// Emit a specific file
const sourceFile = program.getSourceFile('./src/index.ts');
if (sourceFile) {
  program.emit(sourceFile);
}

// Emit only declaration files
program.emit(undefined, undefined, undefined, true);

// Custom write file callback
program.emit(
  undefined,
  (fileName, data, writeByteOrderMark) => {
    console.log(`Writing: ${fileName}`);
    ts.sys.writeFile(fileName, data, writeByteOrderMark);
  }
);

Utility Methods

getCurrentDirectory()

Returns the current working directory.
return
string
The current directory path
const currentDir = program.getCurrentDirectory();
console.log('Current directory:', currentDir);

getNodeCount()

Returns the total number of AST nodes in the program.
return
number
Total node count
console.log('Total nodes:', program.getNodeCount());

getIdentifierCount()

Returns the total number of identifiers in the program.
return
number
Total identifier count
console.log('Total identifiers:', program.getIdentifierCount());

getSymbolCount()

Returns the total number of symbols in the program.
return
number
Total symbol count
console.log('Total symbols:', program.getSymbolCount());

getTypeCount()

Returns the total number of types in the program.
return
number
Total type count
console.log('Total types:', program.getTypeCount());

isSourceFileFromExternalLibrary(file: SourceFile)

Determines if a source file is from an external library.
file
SourceFile
required
The source file to check
return
boolean
True if the file is from an external library
const sourceFile = program.getSourceFile('./node_modules/lodash/index.d.ts');
if (sourceFile && program.isSourceFileFromExternalLibrary(sourceFile)) {
  console.log('This is an external library file');
}

isSourceFileDefaultLibrary(file: SourceFile)

Determines if a source file is from the default library (e.g., lib.d.ts).
file
SourceFile
required
The source file to check
return
boolean
True if the file is from the default library
for (const sourceFile of program.getSourceFiles()) {
  if (program.isSourceFileDefaultLibrary(sourceFile)) {
    console.log(`Default lib: ${sourceFile.fileName}`);
  }
}

Creating a Compiler Host

ts.createCompilerHost()

Creates a default CompilerHost implementation that uses the file system.
function createCompilerHost(
  options: CompilerOptions,
  setParentNodes?: boolean
): CompilerHost
options
CompilerOptions
required
Compiler options to configure the host
setParentNodes
boolean
Whether to set parent nodes in the AST (default: false)
Returns: A CompilerHost instance with default file system operations.

Example

import * as ts from 'typescript';

const options: ts.CompilerOptions = {
  target: ts.ScriptTarget.ES2020,
  module: ts.ModuleKind.CommonJS,
  strict: true
};

// Create a compiler host
const host = ts.createCompilerHost(options);

// Optionally customize host methods
const originalGetSourceFile = host.getSourceFile;
host.getSourceFile = (fileName, languageVersion, onError, shouldCreateNewSourceFile) => {
  console.log(`Reading file: ${fileName}`);
  return originalGetSourceFile(fileName, languageVersion, onError, shouldCreateNewSourceFile);
};

// Use the custom host with createProgram
const program = ts.createProgram({
  rootNames: ['./src/index.ts'],
  options,
  host
});

Transpiling Single Files

ts.transpileModule()

Transpiles a single TypeScript source string to JavaScript without type checking.
function transpileModule(
  input: string,
  transpileOptions: TranspileOptions
): TranspileOutput
input
string
required
TypeScript source code as a string
transpileOptions
TranspileOptions
required
compilerOptions
CompilerOptions
Compiler options for transpilation
fileName
string
Optional file name (used for source maps)
reportDiagnostics
boolean
Whether to report diagnostics
moduleName
string
Module name for AMD/UMD output
transformers
CustomTransformers
Custom transformers to apply
Returns: TranspileOutput with properties:
  • outputText: The transpiled JavaScript code
  • diagnostics: Optional array of diagnostics
  • sourceMapText: Optional source map as a string

Example

import * as ts from 'typescript';

const source = `
  const greet = (name: string): string => {
    return \`Hello, \${name}!\`;
  };
  
  console.log(greet("TypeScript"));
`;

const result = ts.transpileModule(source, {
  compilerOptions: {
    target: ts.ScriptTarget.ES2015,
    module: ts.ModuleKind.CommonJS
  }
});

console.log(result.outputText);
// Output:
// const greet = (name) => {
//     return `Hello, ${name}!`;
// };
// console.log(greet("TypeScript"));
transpileModule is fast but doesn’t perform type checking. Use createProgram with a full compilation for type checking.

Complete Example

import * as ts from 'typescript';

// Create a program
const program = ts.createProgram({
  rootNames: ['./src/index.ts'],
  options: {
    target: ts.ScriptTarget.ES2020,
    module: ts.ModuleKind.CommonJS,
    strict: true,
    declaration: true,
    outDir: './dist'
  }
});

// Get all diagnostics
const allDiagnostics = ts.getPreEmitDiagnostics(program);

if (allDiagnostics.length > 0) {
  allDiagnostics.forEach(diagnostic => {
    if (diagnostic.file) {
      const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(
        diagnostic.start!
      );
      const message = ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
      console.log(
        `${diagnostic.file.fileName} (${line + 1},${character + 1}): ${message}`
      );
    } else {
      console.log(ts.flattenDiagnosticMessageText(diagnostic.messageText, '\n'));
    }
  });
} else {
  console.log('No errors found');
  
  // Emit the output files
  const emitResult = program.emit();
  
  if (emitResult.emitSkipped) {
    console.log('Emit was skipped');
  } else {
    console.log('Compilation successful');
  }
  
  // Print statistics
  console.log(`\nStatistics:`);
  console.log(`  Nodes: ${program.getNodeCount()}`);
  console.log(`  Identifiers: ${program.getIdentifierCount()}`);
  console.log(`  Symbols: ${program.getSymbolCount()}`);
  console.log(`  Types: ${program.getTypeCount()}`);
}

See Also

Build docs developers (and LLMs) love