Ts中的泛型函数总结keyof

本文详细讲解了 TypeScript 中的关键操作符 keyof,以及 Partial、Required、Readonly 和 Omit 的功能和用法示例,帮助开发者更好地操纵类型和创建灵活的类型系统。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

keyof

TypeScript中的keyof操作符,是将一个类型映射为它所有成员名称的联合类型。

interface Person {
  name: string;
  age: number;
  gender: string;
}
type P = keyof Person; // "name" | "age" | "gender"

// 我们可以看到,keyof将Person这个对象类型映射成了一个联合类型
// 因此我们可以更方便的操作这个联合类型
Partial

Partial的作用是将传入的属性变成可选项,原理就是使用keyof拿到所有属性名,然后再使用in[遍历],T[P]拿到相应的值。

type Partial<T> = { [P in keyof T]?: T[P] }
//作用:生成一个新类型,该类型与 T 拥有相同的属性,但是所有属性皆为可选项

看看使用实列

interface Foo {
    name: string
    age: number
}
type Bar = Partial<Foo>
// 相当于
type Bar = {
    name?: string
    age?: number
}

Required

Required 的作用是将传入的属性变为必选项,原理是使用-?将可选项的?去掉。与之对应的还有个+?。

type Require<T> = { [p in keyof T]-?: T[P] }

例子

interface Foo {
    name: string
    age?: number
}
type Bar = Required<Foo>
// 相当于
type Bar = {
    name: string
    age: string
}
Readonly

Readonly的作用是将传入的属性变为只读选项

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

Mutable的作用是将传入属性的readonly移除。

This is useful as a lightweight builder for a type with readonly properties (especially useful when some of the properties are optional and conditional logic is needed before assignment).

type Mutable<T> = {
  -readonly[P in keyof T]: T[P]
};
type Mutable<T> = {-readonly[P in keyof T]: T[P]};
 interface Foobar {
   readonly a: number;
   readonly b: number;
   readonly x?: string;
 }

 function newFoobar(baz: string): Foobar {
   const foobar: Mutable<Foobar> = {a: 1, b: 2};
   if (shouldHaveAnX(baz)) {
     foobar.x = 'someValue';
   }

   return foobar;
 }

Record

Record的作用是将K中所有属性的值转化成T类型

Record<K,T>构造具有给定类型T的一组属性K的类型。在将一个类型的属性映射到另一个类型的属性时,Record非常方便。他会将一个类型的所有属性值都映射到另一个类型上并创造一个新的类型.

type Record<K extends keyof any, T> = {
    [P in K]: T;
};
type petsGroup = 'dog' | 'cat' | 'fish';
interface IPetInfo {
    name:string,
    age:number,
}

type IPets = Record<petsGroup, IPetInfo>;

const animalsInfo:IPets = {
    dog:{
        name:'dogName',
        age:2
    },
    cat:{
        name:'catName',
        age:3
    },
    fish:{
        name:'fishName',
        age:5
    }
}
Pick

Pick的作用是从T中取出一系列K的属性

type Pick<T, K extends keyof T> = { [P in K]: T[P]; };
interface Person {
  name: string;
  age: number;
  id: number;
  sex: 0 | 1;
}

// 问女生年纪不太礼貌,所以我们不需要 age 这个属性
type Woman = Pick<Person, "name" | "id">;

// 此时 Woman 等效于 Female

interface Female {
  name: string;
  id: number;
}
Exclude

Exclude的作用是从T中找出U中没有的元素

type Exclude<T, U> = T extends U ? never : T;

type A = Exclude<'key1' | 'key2', 'key2'> 
// 'key1'

这个定义就利用了条件类型中的分配原则,来尝试将实例拆开看看发生了什么:

type A = `Exclude<'key1' | 'key2', 'key2'>`

// 等价于

type A = `Exclude<'key1', 'key2'>` | `Exclude<'key2', 'key2'>`

// =>

type A = ('key1' extends 'key2' ? never : 'key1') | ('key'2 extends 'key2' ? never : 'key2')

// =>

// never是所有类型的子类型
type A = 'key1' | never = 'key1'
Extract

高级类型Extract和上面的Exclude刚好相反,它是将第二个参数的联合项从第一个参数的联合项中提取出来,当然,第二个参数可以含有第一个参数没有的项。

下面是其定义和一个例子,有兴趣可以自己推导一下

type Extract<T, U> = T extends U ? T : never 
type A = Extract<'key1' | 'key2', 'key1'> // 'key1'
Omit

Omit的作用是忽略对象的某些属性功能
它的作用主要是:以一个类型为基础支持剔除某些属性,然后返回一个新类型。

type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
type Person = {
    name: string;
    age: string;
    location: string;
};

type PersonWithoutLocation = Omit<Person, 'location'>;

// PersonWithoutLocation equal to QuantumPerson
type QuantumPerson = {
    name: string;
    age: string;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值