TypeScript声明合并详解二
接上篇文章
命名空间与类/函数/枚举合并
命名空间可以与其他类型的声明合并:
与类合并:
class Person {constructor(public name: string) {}
}namespace Person {export function createAnonymous() {return new Person("Anonymous");}
}const person1 = new Person("Alice");
const person2 = Person.createAnonymous();与函数合并:
function buildName(firstName: string, lastName?: string) {// ...
}namespace buildName {export interface Options {firstName: string;lastName?: string;}export function fromOptions(options: Options) {return buildName(options.firstName, options.lastName);}
}buildName("John", "Doe");
buildName.fromOptions({ firstName: "Jane" });与枚举合并:
enum Color {Red = 1,Green = 2,Blue = 4
}namespace Color {export function mix(color1: Color, color2: Color) {return color1 | color2;}
}const yellow = Color.mix(Color.Red, Color.Green);合并顺序规则
合并的顺序会影响最终结果:
接口内部的声明按书写顺序合并
后面的接口具有更高优先级
对于函数重载,后面的接口出现在更前面
interface Cloner {clone(animal: Animal): Animal;
}interface Cloner {clone(animal: Sheep): Sheep;
}interface Cloner {clone(animal: Dog): Dog;clone(animal: Cat): Cat;
}// 合并后的顺序:
// clone(animal: Dog): Dog;
// clone(animal: Cat): Cat;
// clone(animal: Sheep): Sheep;
// clone(animal: Animal): Animal;实际应用场景
1. 扩展第三方库类型
// 扩展 express 的 Request 类型
declare namespace Express {export interface Request {user?: {id: string;name: string;};}
}2. 为现有类添加静态方法
class Calculator {static add(a: number, b: number): number {return a + b;}
}namespace Calculator {export function multiply(a: number, b: number): number {return a * b;}
}3. 模块增强
// user.ts
export interface User {id: string;name: string;
}// user-extension.ts
import { User } from './user';declare module './user' {interface User {email?: string;age?: number;}
}// 现在 User 接口包含了扩展的属性注意事项
类型冲突:合并时类型必须兼容,否则会报错
模块增强:使用
declare module语法时需要注意模块路径可读性:过度使用声明合并可能会降低代码可读性
