外部模块声明
外部模块声明
TypeScript 的外部模块声明允许开发者描述非 TypeScript 编写的库或模块的形状。当使用 JavaScript 库时,这些声明文件(通常以 .d.ts
结尾)提供了类型信息,使得 TypeScript 能够进行类型检查并提供智能提示。
声明文件基础
外部模块声明通常放在 .d.ts
文件中。这些文件不包含实现,只包含类型信息。例如,对于一个简单的 JavaScript 库:
// math.js
function add(a, b) {
return a + b;
}
对应的声明文件可能是:
// math.d.ts
declare function add(a: number, b: number): number;
模块声明语法
完整的模块声明使用 declare module
语法。例如,为流行的 lodash 库创建声明:
declare module 'lodash' {
export function chunk<T>(array: T[], size?: number): T[][];
export function compact<T>(array: T[]): T[];
// 更多方法声明...
}
全局扩展
有时需要扩展全局作用域中的类型。例如,为 String
添加自定义方法:
// global.d.ts
declare global {
interface String {
toTitleCase(): string;
}
}
然后在代码中实现:
String.prototype.toTitleCase = function() {
return this.replace(/\w\S*/g, txt =>
txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase()
);
};
第三方库的类型定义
对于流行的 JavaScript 库,通常可以通过 DefinitelyTyped 获取类型定义。安装方式:
npm install --save-dev @types/lodash
复杂模块示例
考虑一个假设的图表库 chart-lib
,它导出一个 Chart
类和多个接口:
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;
}
}
命名空间合并
当模块既有默认导出又有命名导出时,可以这样声明:
declare module 'complex-module' {
export function helper(): void;
namespace complexModule {
export const version: string;
export interface Config {
debug: boolean;
}
}
export default complexModule;
}
条件类型和模块
在高级场景中,可能需要根据环境变量改变模块类型:
declare module 'config' {
export const apiUrl: string;
export const timeout: number;
if (process.env.NODE_ENV === 'development') {
export const debugMode: true;
}
}
模块重定向
有时需要将模块导入重定向到其他位置:
declare module 'old-library' {
import * as newLibrary from 'new-library';
export = newLibrary;
}
处理 CommonJS 和 AMD
对于不同的模块系统,声明方式略有不同。CommonJS 模块:
declare module 'legacy-module' {
function createInstance(options?: object): any;
export = createInstance;
}
类型推断增强
当模块导出复杂对象时,可以使用类型推断:
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;
}
动态模块加载
对于动态导入的模块,可以这样声明:
declare module 'dynamic/*' {
const content: {
default: React.ComponentType;
metadata: object;
};
export default content;
}
处理 CSS 和资源文件
在模块系统中处理非 JavaScript 资源:
declare module '*.css' {
const classes: { [key: string]: string };
export default classes;
}
declare module '*.png' {
const value: string;
export default value;
}
模块版本控制
处理不同版本的模块类型:
declare module 'some-library/v1' {
export function oldAPI(): void;
}
declare module 'some-library/v2' {
export function newAPI(): void;
}
全局变量声明
虽然不是严格意义上的模块,但全局变量声明也类似:
declare const __VERSION__: string;
declare const __DEV__: boolean;
模块扩展模式
扩展已有模块的类型:
import { Original } from 'original-module';
declare module 'original-module' {
interface Original {
newMethod(): void;
}
}
复杂泛型模块
带有泛型的模块声明示例:
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
上一篇:三斜线指令