批量设置属性全部只读

interface ObjInterface {
    a: number;
    b: number;
    c: number;
}


//全部设为只读
type readonlyObj = Readonly<ObjInterface>;

鼠标移动到readonlyObj可以发现所有的属性全部设置为只读了。

type readonlyObj = {
    readonly a: number;
    readonly b: number;
    readonly c: number;
}

我们按住ctrl+鼠标左键点击Readonly;可以看到ts的相关实现:

type Readonly<T> = {
    readonly [P in keyof T]: T[P];
}

ts官方定义了一个Readonly类型,它有一个泛型T,类型的属性会通过keyof拿到T的所有key的联合类型,然后P in相当于进行了一个for循环,把联合类型中的对应的每个key值都赋值到P上,P自身又readonly了,值则是T[P],可以理解为对象obj[key]

批量可选

interface ObjInterface {
    a: number;
    b: number;
    c: number;
}


//全部设为可选
type partialObj = Partial<ObjInterface>;

鼠标移动到partialObj可以看到所有的属性都变成了可选

type partialObj = {
    a?: number;
    b?: number;
    c?: number;
}

我们按住ctrl+鼠标左键点击Partial;可以看到ts的相关实现:

type Partial<T> = {
    [P in keyof T]?: T[P];
}

原理和批量只读一样,只是这里改用了?:可选了。

指定属性key生成新的声明

我们需要生成一个新的类型声明,但是只需要ObjInterface的a和b属性。

interface ObjInterface {
    a: number;
    b: number;
    c: number;
}


//生成指定属性声明
type pickObj = Pick<ObjInterface,"a"|"b">

得到如下:

type pickObj = {
    a: number;
    b: number;
}

Pick的实现:

type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
}

它有两个泛型,第一个是源参,第二个是需要使用到的key值联合类型,并且必须是来源于T的。

剩下就是in循环了。

已知属性赋值到指定key并生成新的声明

比如说我有一个对象,里面有a、b、c三个属性都是布尔值,这三个key对应的都是同一个类型。

interface ObjInterface {
    a: number;
    b: number;
    c: number;
}


//已知属性赋值到指定key并生成新的声明
type recordObj = Record<"a"|"b"|"c",ObjInterface>

得到:

type recordObj = {
    a: ObjInterface;
    b: ObjInterface;
    c: ObjInterface;
}

Record实现:

type Record<K extends string, T> = {
    [P in K]: T;
}

这里就不太清楚为啥K要继承string

实战例子:

interface CatInfo {
  age: number;
  breed: string;
}
 
type CatName = "miffy" | "boris" | "mordred";
 
const cats: Record<CatName, CatInfo> = {
  miffy: { age: 10, breed: "Persian" },
  boris: { age: 5, breed: "Maine Coon" },
  mordred: { age: 16, breed: "British Shorthair" },
};
 
cats.boris;
分类: TypeScript 标签: TypeScript映射类型ReadonlyPartialPickRecord

评论

暂无评论数据

暂无评论数据

目录