External module declaration
External Module Declarations
TypeScript's external module declarations allow developers to describe the shape of libraries or modules not written in TypeScript. When using JavaScript libraries, these declaration files (typically ending with .d.ts
) provide type information, enabling TypeScript to perform type checking and offer intelligent code completion.
Basics of Declaration Files
External module declarations are usually placed in .d.ts
files. These files contain no implementation—only type information. For example, for a simple JavaScript library:
// math.js
function add(a, b) {
return a + b;
}
The corresponding declaration file might be:
// math.d.ts
declare function add(a: number, b: number): number;
Module Declaration Syntax
Full module declarations use the declare module
syntax. For example, creating a declaration for the popular lodash library:
declare module 'lodash' {
export function chunk<T>(array: T[], size?: number): T[][];
export function compact<T>(array: T[]): T[];
// More method declarations...
}
Global Augmentation
Sometimes you need to extend types in the global scope. For example, adding a custom method to String
:
// global.d.ts
declare global {
interface String {
toTitleCase(): string;
}
}
Then implement it in your code:
String.prototype.toTitleCase = function() {
return this.replace(/\w\S*/g, txt =>
txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()
);
};
Type Definitions for Third-Party Libraries
For popular JavaScript libraries, type definitions are often available via DefinitelyTyped. Installation method:
npm install --save-dev @types/lodash
Complex Module Example
Consider a hypothetical chart library chart-lib
that exports a Chart
class and several interfaces:
declare module 'chart-lib' {
export interface ChartOptions {
width?: number;
height?: number;
theme?: 'light' | 'dark';
}
export interface DataPoint {
x: number;
y: number;
label?: string;
}
export class Chart {
constructor(container: HTMLElement, options?: ChartOptions);
render(data: DataPoint[]): void;
destroy(): void;
}
}
Namespace Merging
When a module has both default and named exports, you can declare it like this:
declare module 'complex-module' {
export function helper(): void;
namespace complexModule {
export const version: string;
export interface Config {
debug: boolean;
}
}
export default complexModule;
}
Conditional Types and Modules
In advanced scenarios, you might need to change module types based on environment variables:
declare module 'config' {
export const apiUrl: string;
export const timeout: number;
if (process.env.NODE_ENV === 'development') {
export const debugMode: true;
}
}
Module Redirection
Sometimes you need to redirect module imports to another location:
declare module 'old-library' {
import * as newLibrary from 'new-library';
export = newLibrary;
}
Handling CommonJS and AMD
Declarations differ slightly for different module systems. For CommonJS modules:
declare module 'legacy-module' {
function createInstance(options?: object): any;
export = createInstance;
}
Type Inference Enhancement
When modules export complex objects, you can use type inference:
declare module 'geometry' {
export interface Point {
x: number;
y: number;
}
export interface Circle {
center: Point;
radius: number;
}
export function createCircle(x: number, y: number, radius: number): Circle;
export function area(circle: Circle): number;
}
Dynamic Module Loading
For dynamically imported modules, declare them like this:
declare module 'dynamic/*' {
const content: {
default: React.ComponentType;
metadata: object;
};
export default content;
}
Handling CSS and Asset Files
Handling non-JavaScript resources in module systems:
declare module '*.css' {
const classes: { [key: string]: string };
export default classes;
}
declare module '*.png' {
const value: string;
export default value;
}
Module Versioning
Handling types for different module versions:
declare module 'some-library/v1' {
export function oldAPI(): void;
}
declare module 'some-library/v2' {
export function newAPI(): void;
}
Global Variable Declarations
Though not strictly modules, global variable declarations are similar:
declare const __VERSION__: string;
declare const __DEV__: boolean;
Module Augmentation Patterns
Extending types of existing modules:
import { Original } from 'original-module';
declare module 'original-module' {
interface Original {
newMethod(): void;
}
}
Complex Generic Modules
Example of a module declaration with generics:
declare module 'generic-storage' {
export interface Storage<T = any> {
get(key: string): Promise<T | undefined>;
set(key: string, value: T): Promise<void>;
delete(key: string): Promise<void>;
}
export function createStorage<T>(options?: { prefix?: string }): Storage<T>;
}
本站部分内容来自互联网,一切版权均归源网站或源作者所有。
如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn
上一篇:三斜线指令