Typescript 学习笔记 (泛型应用)

103 阅读2分钟

什么是泛型

一种支持自定义类型传参的高级类型定义

常用泛型工具

Partial<Type>

构造一个新的“类型”,将 Type 的所有属性都设置为可选的类型。

interface UserInfoProps {
  name: string;
  phone: string;
  age?: string;
  remark?: string
}

type UpdateFormProps = Partial<UserInfoProps>

// =>
// type UpdateFormProps = {
//     name?: string;
//     phone?: string;
//     age?: string;
//     remark?: string;
// }

function updateForm (data: UserInfoProps, updateData: UpdateFormProps) {
  return {...data, ...updateData}
}

Required<Type>

构造一个新的类型,将 Type 中所有属性都设置为必选类型,与 Partial<Type> 相反。 由于和 Partial<Type> 用法类似,这里不再示例说明

Record<Keys, Type>

以 Keys 为属性键,Type 为 属性值,构建一个对象。

interface AnimalInfo {
  age: number;
  name: string;
}

type AnimalType = 'cat' | 'dog' | 'panda';

const Animals: Record<AnimalType, AnimalInfo> = {
  cat: { age: 10, name: 'cat' },
  dog: { age: 5, name: 'dog' },
  panda: { age: 16, name: 'panda' },
};

Pick<Type, Keys>

通过拾取 Type 类型中所有 keys 对应的 key: value,构建一个新的类型

interface Todo {
  title: string;
  description: string;
  completed: boolean;
}
 
type TodoPreview = Pick<Todo, "title" | "completed">;

// =>
// type TodoPreview = {
//     title: string;
//     completed: boolean;
// }
 
const todo: TodoPreview = {
  title: "Clean room",
  completed: false,
};

Omit<Type, Keys>

通过移除 Type 类型中 keys 对应的 key: value, 构建一个新的类型。

interface Todo {
    title: string;
    description: string;
    completed: boolean;
    createdAt: number;
}

type TodoPreview = Omit<Todo, "description">;

// =>
// type TodoPreview = {
//     title: string;
//     completed: boolean;
//     createdAt: number;
// }

const todo: TodoPreview = {
    title: "Clean room",
    completed: false,
    createdAt: 1615544252770,
};

Exclude<UnionType, ExcludedMembers>

通过从 UnionType 中排除所有可分配给 Excldedmembers 的联合成员来构造一个类型。

type T0 = Exclude<'a' | 'b' | 'c', 'a'>;
// => T0 = 'a' | 'b'

type T1 = Exclude<'a' | 'b' | 'c', 'a' | 'b'>;
// => T1 = 'a'

type T2 = Exclude<string | number | (() => void), Function>;
// => T2 = 'string' | 'number'

Extract<UnionType, Members>

UnionType 类型中提取所有可赋值给 Members 的成员类型,构造一个新的类型。

export type T3 = Extract<'a' | 'b' | 'c', 'a' | 'b'>;
// => T3 = 'a' | 'b'

export type T4 = Extract<string | number | (() => void), Function>;
// => T4 = () => void

更多泛型工具可查看 Typescript handhook Unility Types

项目实践

组件二次封装

@ant-design/pro-components 组件库中 ProTable 为例,进行二次封装。 对于泛型定义的组件,只需以同样的方式进行类型传参即可,需要指定默认类型时,按照原组件定义的类型直接引入。

import { ProTable, ProTableProps } from '@ant-design/pro-components';

import type { ParamsType } from '@ant-design/pro-provider';

const ProProTable = <
  T extends Record<string, any>,
  U = ParamsType,
  ValueType = 'text',
>(props: ProTableProps<T, U, ValueType>) => {
  const { toolbar, columnsState } = props;

  return (
    <ProTable
      columnsState={{ persistenceType: 'localStorage', ...columnsState }}
      toolbar={toolbar}
      {...props}
    />
  );
}

export default ProProTable;