对象类型
简介
对象是 JavaScript 中的一种数据类型,它是一种无序的数据集合,由键值对组成。
声明对象最简单的方式是使用对象字面量表示法,即使用花括号{}
包裹键值对。书写方式和 JavaScript 保持一致:
typescript
const person = {
name: 'Tom',
age: 18,
}
此时,TS会自动推导类型,person
的类型为 { name: string, age: number }
。
定义对象类型则稍有不同:
typescript
type Person = {
name: string,
age: number,
}
不同的属性之间可以使用逗号分隔,也可以使用分号分隔,甚至什么都不写也是可以的。
一旦明确定义了对象类型,就必须一一对应属性,不能多也不能少:
typescript
type Person = {
name: string,
age: number,
}
const person: Person = {
name: 'Tom',
age: 18,
}
可选属性
如果对象的某个属性是可选的,可以在属性名后加上?
:
typescript
type Person = {
name: string,
age?: number,
}
const person1: Person = {
name: 'Tom'
}
同样的,在读取可选属性时,需要先判断该属性是否存在:
typescript
if (person1.age !== undefined) {
console.log(person1.age)
}
只读属性
对象的属性可以设置为只读,即只能在声明时或构造函数中赋值,使用readonly
关键字表示:
typescript
type Person = {
readonly name: string,
age: number,
}
const person2: Person = {
name: 'Tom',
age: 18,
}
person2.name = 'Jerry' // Error: Cannot assign to 'name' because it is a read-only property
如果只读属性是对象类型,此时对象的属性可以被修改,但限制是不能替换整个对象:
typescript
type Person = {
readonly address: {
city: string,
street: string,
},
age: number,
}
const p: Person = {
address: {
city: '北京',
street: '朝阳',
},
age: 18,
}
p.address.city = '上海' // ✅
p.address = { city: '广州', street: '天河' } // Error: Cannot assign to 'address' because it is a read-only property
属性索引类型
有时候,一个对象的属性个数是不确定的,这时候只能用表达式定义这些属性,TS称之为索引类型:
typescript
type Person = {
[key: string]: string,
}
const p: Person = {
name: 'Tom',
address: '北京',
hobby: '摸鱼🐟',
}
如上所示,只要键值的类型符合索引类型,可以不断添加新的属性(属性名不能重复)。
根据Javascript的定义,合法对象的属性名只能是字符串、数字或者Symbol。
需要注意的是,数值索引不能与字符串索引共用,因为JS内部会将数值索引转换为字符串索引:
typescript
type Person = {
[key: string]: string,
[key: number]: string, // Error: Numeric index type 'number' is not assignable to string index type 'string'
}