# TypeScript 的声明合并
声明合并就是将两个或以上的独立声明合并为一个声明,这个声明会拥有之前所有声明的特性。
# 关于声明
声明是 typescript 功能的基础,一个声明会创建一个实体,共有三种方式创建。
1.类型:使用 type 或 interface 关键字来定义一个类型。此外 class 和 enum 也会得到一个类型。
2.值:使用 const,let,var,function,class,enum 等创建值的方式也会得到一个声明。
3.命名空间:使用 namespace 来声明一个命名空间,其会创建一个命名空间和值。
笔记
命名空间的声明,创建一个命名空间和一个值;变量的声明只会创建一个值;interface 和 type 的声明只会创建一个类型;而 class
和 enum
的声明,既会创建一个值,也会创建一个同名的类型。
# 合并 interface 的声明
interface 的声明的合并是最简单的了,只需重复声明就会自动合并。
如果有重名字段,该字段类型必须相同否则就会报错。
interface A {
name: string,
age: number,
}
interface A {
name: string,
gender: 1 | 2,
}
/*
A 接口为 {
name: string,
age: number,
gender: 1 | 2,
}
*/
interface B {
name: string,
age: number,
}
interface B {
// 报错,同名字段age,对应的类型不同,分别为number和string
age: string,
gender: 1 | 2,
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
合并非重名接口
type Target<A, B> = A & Omit<Partial<B>, keyof A>
1
# 合并 namespace 命名空间
namespace 的声明合并方式与 interface 相似,重复声明就会自动合并,而且命名空间和值都会合并。
// 声明两个独立的命名空间
namespace Animals {
export class Zebra {}
}
namespace Animals {
export interface Legged {
numberOfLegs: number;
}
export class Dog {}
}
/* 会被合并为:
namespace Animals {
export interface Legged {
numberOfLegs: number;
}
export class Zebra {}
export class Dog {}
}
*/
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
如果想要在同名 namespace 中获取另一个 namespace 的值,可以通过 export 来共享该成员。
namespace Person {
export let name = "cc" // 导出值
export function getName(){
return name
}
}
namespace Person {
export function setName(str: string){
name = str // 可以获取同名命名空间中导出的值
}
}
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
# 将 namespace 与 class、function、enum 合并
namespace 不仅可以和 namespace 合并,同时还能与 class、function、enum 进行合并。
# 与类合并
命名空间中导出的成员,会成为同名的class的静态成员,而没有导出的成员,则无法在被class获取。
class Album {
label: Album.AlbumLabel;
}
namespace Album {
export class AlbumLabel {};
export const name = "cc";
let age = 18;
}
Album.name // "cc"
Album.age // 报错
const album = new Album()
album.name // 报错,没有实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
# 与函数合并
命名空间中导出的成员,会成为函数的属性。
function logName(str: string){
console.log(str + logName.name)
}
namespace logName {
export const name = "cc"
export const age = 18
let gender = 1
}
logName("yy")
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
# 与枚举合并
命名空间中导出的成员,会成为枚举的扩充。
enum Color {
red = 1,
green = 2,
blue = 4,
}
namespace Color {
export function mixColor(colorName: string) {
if (colorName == "yellow") {
return Color.red + Color.green;
}
}
export const pink = 10
}
Color.mixColor("yellow") // 3
Color.pink // 10
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16