Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

Dynamic imports in TypeScript utilize the import() function expression to load modules asynchronously at runtime, returning a Promise that resolves to the module namespace object. TypeScript integrates this ECMAScript feature by providing strict static type inference for the resolved module, provided the module specifier is statically analyzable.

Syntax and Resolution

The import() expression accepts a module specifier string. When statically analyzable, TypeScript automatically infers the resolved Promise payload as the exact shape of the target module’s exports.
// math.ts
export const add = (a: number, b: number): number => a + b;
export interface MathConfig { strict: boolean; }

// main.ts
async function loadMathModule() {
  const mathModule = await import('./math');
  // mathModule is strictly typed as: typeof import("./math")
  const result: number = mathModule.add(5, 10);
}

Static Analyzability and String Literal Expressions

For TypeScript to successfully infer the types of a dynamically imported module, the module specifier must be a string literal expression (an inline string AST node). TypeScript does not resolve dynamic imports from variables, even if those variables possess a strict string literal type or a union of string literal types. Passing anything other than an inline string literal expression causes the compiler to abandon type resolution, degrading the return type to Promise<any>.
// Statically analyzable: Inline string literal expression
const { add } = await import('./math'); 
// 'add' is strictly typed as: (a: number, b: number) => number

// Non-statically analyzable: Variable with a string literal type
const modulePath: './math' = './math';
const dynamicModule = await import(modulePath); 
// dynamicModule is typed as 'any'

// Non-statically analyzable: Union type
function load(path: './math' | './utils') {
  return import(path); 
  // Returns Promise<any>, NOT Promise<typeof import('./math') | typeof import('./utils')>
}

Type Extraction via typeof import

TypeScript allows developers to reference the type of a dynamically imported module in the type space without triggering the runtime import. This is achieved using the typeof import("...") type query.
// Extracts the entire module namespace type
type MathModule = typeof import('./math');

// Extracts the type signature of a specific exported value
type AddFunction = typeof import('./math').add;

// Extracts an exported type/interface
type Config = import('./math').MathConfig;

Inline Type Imports

The import("...") syntax can be used directly within type annotations. This mechanism resolves types from external modules inline, which is heavily utilized in declaration files (.d.ts) or to prevent polluting the module scope with static imports solely for type checking.
// Variable annotation using inline dynamic import type
let config: import('./math').MathConfig;

// Function parameter annotation
function initialize(options: import('./math').MathConfig): void {
  // Implementation
}

Compiler Configuration (tsconfig.json)

The emitted JavaScript for an import() expression is dictated by the module setting in the TypeScript compiler options:
  • ESNext, ES2020, Node16, NodeNext: TypeScript preserves the import() statement in the emitted JavaScript, delegating the asynchronous resolution to the native environment’s module loader.
  • CommonJS: TypeScript transpiles the import() expression into a Promise wrapper around the synchronous require() function to simulate asynchronous loading.
{
  "compilerOptions": {
    "module": "NodeNext",
    "moduleResolution": "NodeNext"
  }
}
Master TypeScript with Deep Grasping Methodology!Learn More