Skip to content

对象类型

简介

对象是 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'
}