Type import and export
Basic Concepts of Type Import and Export
The type import and export mechanism in TypeScript allows developers to modularize type definitions and share them across different files. This mechanism is tightly integrated with JavaScript's module system but adds support at the type level. Using the import
and export
keywords, types can be handled just like values, making code organization clearer.
// types.ts
export interface User {
id: number;
name: string;
}
export type Status = 'active' | 'inactive';
Default and Named Exports
Type exports support two main forms: named exports and default exports. Named exports allow multiple types to be exported from a module, while default exports are suitable for scenarios where the module's primary type is being exported.
// Named export example
export interface Product {
sku: string;
price: number;
}
export function calculateTax(price: number): number {
return price * 0.1;
}
// Default export example
export default class ShoppingCart {
items: Product[] = [];
}
The corresponding syntax for imports is as follows:
// Import named exports
import { Product, calculateTax } from './models';
// Import default exports
import ShoppingCart from './ShoppingCart';
Type-Only Import Syntax
TypeScript provides syntax specifically for type imports, which can clearly distinguish between type imports and value imports. This is particularly useful in certain compilation optimization scenarios.
import type { User } from './types';
import { type User, getUser } from './api';
// Pure type imports are completely removed after compilation
Re-export Patterns
Modules can re-export types from other modules, which is especially useful when creating aggregated modules or library entry files.
// utils/index.ts
export { formatDate } from './date';
export { parseQuery } from './url';
export type { QueryParams } from './url'; // Only re-export types
Dynamic Type Imports
TypeScript 4.5+ supports typed dynamic imports, allowing dynamic module loading while maintaining type safety.
const loadUserModule = async () => {
const userModule = await import('./user');
const user: userModule.User = { id: 1, name: 'Alice' };
return user;
};
Type Exports in Namespaces
When using exports within namespaces, types and values can be mixed, but their different behaviors must be noted.
namespace Geometry {
export interface Point {
x: number;
y: number;
}
export class Circle {
constructor(public center: Point, public radius: number) {}
}
}
// Use the exported types and classes
const center: Geometry.Point = { x: 0, y: 0 };
const circle = new Geometry.Circle(center, 10);
Type Exports and Generics
Generic types can also be exported, and type parameters must be provided when using them.
// data-structures.ts
export interface List<T> {
items: T[];
add(item: T): void;
get(index: number): T | undefined;
}
// Use the exported generic interface
import { List } from './data-structures';
const numberList: List<number> = {
items: [1, 2, 3],
add(item) { this.items.push(item); },
get(index) { return this.items[index]; }
};
Conditional Types and Exports
Advanced type features like conditional types can also be exported, enhancing the expressiveness of the type system.
// type-utils.ts
export type NonNullable<T> = T extends null | undefined ? never : T;
export type Flatten<T> = T extends Array<infer U> ? U : T;
// Use conditional types
import { NonNullable, Flatten } from './type-utils';
type ValidString = NonNullable<string | null>; // string
type ElementType = Flatten<string[][]>; // string[]
Type Exports and Third-Party Declarations
When dealing with third-party library types, it is often necessary to extend or override existing type definitions.
// react-extensions.d.ts
import * as React from 'react';
declare module 'react' {
export interface Component {
$customMethod?: () => void;
}
}
// Use the extended type
const component: React.Component = /* ... */;
component.$customMethod?.();
Type Exports and Configuration
Settings in tsconfig.json
can affect the behavior of type imports and exports, especially options like moduleResolution
and paths
.
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@models/*": ["src/models/*"]
}
}
}
Then you can import like this:
import { User } from '@models/types';
Type Exports and Performance Considerations
Extensive use of type imports and exports can impact compilation performance. TypeScript 3.8 introduced import type
to help reduce unnecessary type dependencies.
// Avoid importing types as values
import type { BigConfig } from './config';
// Types not needed at runtime will be removed
function configure(config: BigConfig) {
// ...
}
Type Exports and Module Systems
Different module systems (CommonJS/ESM) handle type exports slightly differently, especially in scenarios where types and values are mixed.
// CommonJS-style export
interface DbConfig {
host: string;
port: number;
}
const connect = (config: DbConfig) => { /*...*/ };
export = {
connect,
DbConfig // Exporting types in CommonJS requires additional handling
};
Type Exports and Toolchain Integration
Build tools like webpack and rollup vary in their support for type imports and exports, and additional plugins may be needed.
// Use webpack's require.ensure with types
declare function requireEnsure<T>(path: string): Promise<T>;
const loadModule = async () => {
const { default: Component } = await requireEnsure<{
default: React.ComponentType
}>('./AsyncComponent');
return Component;
};
Type Exports and Testing
When handling type imports and exports in testing environments, it may be necessary to mock types or create test-specific type variants.
// Test-specific type extension
interface TestUser extends User {
testData?: string;
}
function createTestUser(overrides: Partial<TestUser>): TestUser {
return {
id: 1,
name: 'Test',
...overrides
};
}
Type Exports and Documentation Generation
Tools like TypeDoc can automatically generate API documentation based on type exports, keeping documentation in sync with type definitions.
/**
* Represents an application user
* @remarks
* Contains basic user information
*/
export interface User {
/** Unique user identifier */
id: number;
/** User display name */
name: string;
}
Type Exports and Code Splitting
In code-splitting scenarios, type imports and exports must consider type visibility and module boundaries.
// Use dynamic imports to maintain type safety
async function loadComponent() {
const { default: Chart } = await import(
/* webpackChunkName: "chart" */ './ChartComponent'
);
// The Chart component type will be correctly inferred
return <Chart data={[]} />;
}
Type Exports and Monorepo
In monorepo projects, type imports and exports must handle cross-package references, often using the project references feature.
// tsconfig.json
{
"compilerOptions": {
"composite": true
},
"references": [
{ "path": "../shared-types" }
]
}
Then you can import types across projects:
import { SharedType } from '@company/shared-types';
Type Exports and Declaration Merging
Exported interfaces can merge with interfaces of the same name declared elsewhere, which is particularly useful when extending third-party types.
// user-extensions.ts
import { User } from './models';
declare module './models' {
interface User {
lastLogin?: Date;
permissions: string[];
}
}
// Use the merged type
const user: User = {
id: 1,
name: 'Alice',
permissions: ['read', 'write'] // Newly added property
};
Type Exports and Mutable Modules
When dealing with module types that may change, TypeScript's const
assertions and precise type imports must be used.
// Use const assertions to fix import types
import { endpoints } from './config';
type Endpoints = typeof endpoints;
function getEndpoint(key: keyof Endpoints): string {
return endpoints[key];
}
Type Exports and Performance Optimization
For large projects, organizing type imports and exports properly can significantly impact compilation performance and developer experience.
// Use barrel files to organize type exports
// models/index.ts
export * from './user';
export * from './product';
export * from './order';
// Import centrally when using
import { User, Product } from '../models';
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn