TypeScript声明合并

3,096 阅读2分钟

什么是声明合并

是指某个声明的类型对象在文件或项目中反复被定义

哪些对象可能会出现声明合并

  • 函数的合并
  • 接口的合并
  • 类的合并
  • 命名空间的合并
  • 以上四种可能会互相合并

合并的规则

1.函数合并

同名函数如果被重复定义,会被视为函数重载。

function a(params:string):void
function a(params:number):void
function a(params:any):void{}
需要注意的几点
1.在.d.ts声明文件中,不用出现函数实现
2.在.ts文件中,函数的实现必须紧跟在函数声明之后,中间不能参杂其他代码。

如果与命名空间合并,那么命名空间视为扩展该函数的属性。最典型的就是jquery的声明文件中的出现方式

//此处简化
function $(selector: string): any { }
namespace $ {
    export const version = '1.0'
    export const ajax = ()=>{}
}
//为$函数添加了ajax方法和version属性
$.ajax
2.接口合并

接口可以在同文件合并,也可以在不同文件合并。需要注意tsconifg配置能够覆盖到声明的作用域。通常被用来扩展第三方库的功能。

//a.ts
interface IA {
    x: number
}
interface IA {
    y: number
    foo(p: string): string //5
    foo(p: 1): 1 //2 
}
//b.ts
interface IA {
    z: number
    foo(p: 'a'): 'a'  //1
    foo(p: number): number //3
    foo(p: number[]): number[] //4
}
//c.ts
//报错,缺少x,y,z,foo字段
let a:IA={} 
//成功
let b: IA = {
    x: 1,
    y: 1,
    z: 1,
    foo(p: any) { return p }
}
需要注意的几点
1.对于接口的属性来说,不得出现同名属性但是不同类型。
2.对于接口的方法来说,同名方法会视为方法的重载
3.接口中方法的重载顺序:字面量参数优先,按照书写顺序重载。上面的代码后面的1,2,3,4,5注释就是重载顺序
3.命名空间的合并
namespace x {
    export const version = '1'
}
namespace x {
    export const version = '1' //冲突错误
    export const foo=(p:number)=>{}
}

命名空间除了上面能和函数合并意外。还可以和一下几个类型合并

1.与class合并.相当于为class新增了static属性或方法。注意namespace属性无法被实例化对象调用

class X {
    static a:2
}
namespace X {
    export const a = 2 //冲突报错
    export const version = '1.0'
}
X.version // '1.0'

2.与枚举类型合并。相当于为枚举类型增加了一个值。但不能与常量枚举类型合并

//const enum X {} //报错
enum X {
    a=1
}
namespace X {
    export const a = 2 //冲突报错
    export const version = '1.0'
}
x.version // '1.0'

命名空间在与【函数类型或者类类型】合并时,必须出现【函数类型或者类类型】之后。不能写在之前

//顺序错误
namespace X {
    export const a = 2
    export const version = '1.0'
}
class X {
    
}
命名空间可以在不同文件声明合并,只需要注意不能出现重复的属性和方法