TypeScript-索引类型、映射类型

119 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第14天,点击查看活动详情

前言

TypeScript 在开发中,除了基本的内置类型之外,更多时候需要的是由内置类型通过一定方式组合而成的新类型,或者叫做自定义类型。

一般有四种方式用于创建自定义类型:联合交叉索引映射

最近正好学习到了这一部分,总结记录一下,先前写过了TypeScript-联合类型、交叉类型, 继续看看索引类型映射类型

索引类型

索引类型 通常用于描述一个对象的结构,一般写法如下:

interface MyObjectType {
    [key: string]: string;
}

在这里,规定了对象结构类型的属性名称必须是 string ,值必须是 string

注意的是,类型中并没有规定属性名称必须是什么,因为所有符合 string 的数据都可以作为属性的名称;而且作为对象键名,不管怎么写,最后都会被当成 string,如下写法也不会报错,因为都被当成了 string

微信截图_20220814130215.png

但是,访问值的时候,只能使用 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'.
}