对象的类型

TypeScript中,我们定义对象的方式是使用关键字 interface (接口),我理解为是使用 interface 来定义一种约束,让数据的结构满足约束的格式

1
2
3
4
5
6
7
8
9
10
interface Person {
name: string,
sex: string
}

// 这样写会报错,因为我们在Person中定义了name和sex属性,但p中缺少了sex属性
// 使用接口约束的时候不能多一个属性,也不能少一个属性,必须与接口保持一致
const p: Person = {
name: 'antVae'
}

同名

同名 interface 对象类型会进行合并

1
2
3
4
5
6
7
8
9
10
11
interface A {
name: string
}
interface A {
sex: string
}
// 不会报错
let a: A = {
name: 'antVae',
sex: '男'
}

继承

定义某个对象类型时可以继承其他定义对象类型的属性,使用 extends 关键字

1
2
3
4
5
6
7
8
9
10
11
interface A {
name: string
}
interface B extends A {
sex: string
}

const b: B = {
name: 'antVae',
sex: '男'
}

可选属性

定义一个对象类型时,被该对象类型约束的对象必须拥有该对象类型的所有属性,想要某个属性非必须时,可以使用 ? 操作符修饰

1
2
3
4
5
6
7
8
9
// 可选属性的含义表示该属性可以不存在
interface Person {
name: string,
sex?: string
}

const p: person = {
name: 'antVae'
}

任意属性

允许在对象中添加新的任意属性, 写法[propName: string]:any
需要注意的是,一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集

1
2
3
4
5
6
7
8
9
10
11
12
// 定义了[propName: string]: any,允许添加新的任意属性,不会报错
interface Person {
name: string,
sex: string,
[propName: string]: any
}

const p: Person = {
name: 'antVae',
sex: '男',
age: 18
}

只读属性

关键字 readonly, 是不允许被赋值的,只能读取

1
2
3
4
5
6
7
8
9
10
11
12
interface Person {
name?: string,
readonly hobby: string,
[propName: string]: any
}

let p: Person = {
hobby: '爬山',
sex: '男'
}
// 只读属性不允许修改,会报错
p.hobby = '唱歌'

添加函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
interface Person {
name: string,
sex?: string,
[propName: string]: any
hobby: () => void
}

let p: Person = {
name: 'antVae',
sex: '男',
age: 18,
hobby: () => {
console.log('爬山')
}
}