对象是包含一组键值对的实例。值可以是标量、函数、数组、对象等。
基本用法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| // ts let obj = { a: 'obj', // 标量 b: () => {}, // 函数 c: [1, 2, ,3], // 数组 d: { key01: 'a', key02: 'b' } // 对象 } console.log(obj.a) // obj console.log(obj.b()) // 我是函数 console.log(obj.c) // [1, 2, 3] console.log(obj.d) // { key01: 'a', key02: 'b' }
// 编译成js后 var obj = { a: 'obj', // 标量 b: function () { return '我是函数'; }, // 函数 c: [1, 2, 3], // 数组 d: { key01: 'a', key02: 'b' } // 对象 }; console.log(obj.a); console.log(obj.b()); console.log(obj.c); console.log(obj.d);
|
定义对象类型
匿名对象变量
匿名对象是在定义变量时直接使用花括号{},来定义一个对象类型。
1
| const person: { name: string, age: number } = { name: '老王', age: 30 }
|
匿名对象函数
1 2 3 4
| const personFn = (person: { name: string, age: number }) => { console.log(`姓名:${person.name},年龄:${person.age}`) } personFn({ name: '老王', age: 30 }) // 姓名:老王,年龄:30
|
接口类型
从上面的例子可以看出,每次都这样写对象类型会很麻烦,如果遇到使用同一种对象类型的数据时,需要多次写入,增添了工作量。那么这个时候就可以使用接口来定义对象类型,使代码更加可读、易于维护。
1 2 3 4 5 6 7 8 9
| interface Person { name: string, age?: number } const personFn = (person: Person) => { if (person.age !== undefined) console.log(`姓名:${person.name},年龄:${person.age}`) else console.log(`姓名:${person.name}`) } personFn({ name: '老王' }) // 姓名:老王
|
类型别名
类型别名用来给一个类型起个新名字,使用 type 创建类型别名,类型别名不仅可以用来表示基本类型,还可以用来表示对象类型、联合类型、元组和交集。
1 2 3 4 5 6 7 8 9
| type Person = { name: string, age? : number } const personFn = (person: Person) => { if (person.age !== undefined) console.log(`姓名:${person.name},年龄:${person.age}`) else console.log(`姓名:${person.name}`) } personFn({ name: '老王' }) // 姓名:老王
|
属性修饰符
可选属性
对象类型还可以指定它们的部分或全部属性是可选的。为此,请在属性名称后添加 ?
比如我们在填写个人信息时,年龄一般会选择不填写。
1 2 3 4
| const personFn = (person: { name: string, age?: number }) => { console.log(`姓名:${person.name},年龄:${person.age}`) } personFn({ name: '老王' }) // 姓名:老王,年龄:undefined
|
从上面例子的结果可以看出,如果访问了一个不存在的属性age并不会运行错误,而是会返回undefined,所以当我们在读取可选属性中的数据时,尽量在使用这个属性之前检查一下,如下:
1 2 3 4 5
| const personFn = (person: { name: string, age?: number }) => { if (person.age !== undefined) console.log(`姓名:${person.name},年龄:${person.age}`) else console.log(`姓名:${person.name}`) } personFn({ name: '老王' }) // 姓名:老王
|
只读属性
我们使用 readonly 关键字来声明只读属性,属性的值一旦被赋值就不能再次修改。
1 2 3 4 5 6 7 8 9 10 11 12 13
| type Person = { name: string, readonly age: number, readonly sex: string } const person: Person = { name: '老王', age: 30, sex: '男' } person.name = '翠花' person.age = 18 // 报错,只读属性一旦被赋值就不能再次修改 person.sex = '女' // 报错,只读属性一旦被赋值就不能再次修改
|
索引签名
有时你无法提前知道类型属性的所有名称,在这种情况下,你可以使用索引签名来描述可能值的类型。
基本用法
1 2 3 4 5 6 7 8
| interface personInfo { [key: string]: string | number } const person_info: personInfo = { name: '老王', sex: '男' } console.log(person_info) // { name: '老王', sex: '男' }
|
只读索引签名
1 2 3 4 5 6 7 8 9
| interface personInfo { readonly [key: string]: string | number } const person_info: personInfo = { name: '老王', age: 30, sex: '男' } person_info.age = 18 // 报错
|
联合类型索引签名
1 2 3 4 5 6 7 8 9
| interface personInfo { [key: string]: string | number } const person_info: personInfo = { name: '老王', age: 30, sex: '男' } console.log(person_info) // { name: '老王', age: 30, sex: '男' }
|
泛型对象类型
在我们还不知道是什么样子的对象类型时,可以使用 泛型 先占位,等知道后再补充。
1 2 3 4 5 6 7 8 9 10 11
| interface Person<T> { phone: T } const person01: Person<number> = { phone: 13222222222 } const person02: Person<string> = { phone: '020-1111111' } console.log(person01) // { phone: 13222222222 } console.log(person02) // { phone: '020-1111111' }
|