携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情
前言
TypeScript 在开发中,除了基本的内置类型之外,更多时候需要的是由内置类型通过一定方式组合而成的新类型,或者叫做自定义类型。
一般有四种方式用于创建自定义类型:联合、交叉、索引、映射。
最近正好学习到了这一部分,总结记录一下,先前写过了TypeScript-联合类型、交叉类型, 继续看看索引类型、映射类型。
索引类型
索引类型 通常用于描述一个对象的结构,一般写法如下:
interface MyObjectType {
[key: string]: string;
}
在这里,规定了对象结构类型的属性名称必须是 string ,值必须是 string。
注意的是,类型中并没有规定属性名称必须是什么,因为所有符合 string 的数据都可以作为属性的名称;而且作为对象键名,不管怎么写,最后都会被当成 string,如下写法也不会报错,因为都被当成了 string:
但是,访问值的时候,只能使用 string 类型的键名进行访问;
myObj[false] // 报错 Type 'false' cannot be used as an index type.
myObj['false'] // 合法,能够取到值
如果将 key 定为 number 类型,则键名只能是 number, 传入类型其他是错误的:
interface MyObjectType1 {
[key: number]: string
}
const myObj: MyObjectType1 = {
100: '100',
200: '200',
name: '300' // 报错:Type '{ 100: string; 200: string; name: string; }' is not assignable to type 'MyObjectType1'.
}
映射类型
映射类型 类似于 索引类型,同样都是没有直接规定对象的类型的属性,不同的是,索引类型 直接规定键名的类型,而 映射类型 从已经定义好的对象类型中获取键名:
// Animal 对象类型
interface Animal {
type: string;
name: string;
age: number;
weight: number;
}
// 映射类型,从 T 映射出对应的键名和值的类型
type Fish<T> = {
[key in keyof T]: T[key]
}
这里定义了两个对象类型, Animal 是一个普通的对象类型,而 Fish 是一个映射类型,使用 keyof 获取 T 上的键名; 接下来就可以根据上面定义的类型,实现一个数据:
const fish: Fish<Animal> = {
type: 'fish',
name: 'fish',
age: 18,
weight: 500
}
可以 Fish<Animal> 类型上,直接使用 Animal 中定义的类型,不会有任何得到报错提示。
映射类型 只是获取对象类型的键名而已,值的类型并没有明确规定,所以可以用于复制一个对象类型的属性副本,然后更改其值的类型:
// 将所有的属性的值改为 `string` 类型
type Fish<T> = {
[key in keyof T]: string;
}
// 值为 `number` 类型的会报错
const fish: Fish<Animal> = {
type: 'fish',
name: 'fish',
age: 18, // 报错 Type 'number' is not assignable to type 'string'.
weight: 500 // 报错 Type 'number' is not assignable to type 'string'.
}