掌握 TypeScript Omit 泛型,一起完成 Type 挑战,巩固 TypeScript 知识。
实现内置的??Omit<T, K>
??泛型。通过从??T
??中挑选所有属性,然后删除??K
??来构造一个类型。
例如:
interface Todo {
title: string
description: string
completed: boolean
}
type TodoPreview = MyOmit<Todo, 'description' | 'title'>
const todo: TodoPreview = {
completed: false,
}
我们的类型挑战是实现内置的??Omit<Type,Keys>
?泛型,所以让我们首先理解??Omit<Type,Keys>
??泛型的作用。
Omit<Type,Keys>
通过从??Type
??中选择所有属性,然后删除??Keys
??(字符串字面量或字符串字面量的并集),构造一个类型。
对于 TypeScript 的??Omit
??泛型,它的作用是将现有的对象类型转换为新的对象类型。
为了实现上述类型转换,我们需要遍历除 Keys 以外的所有类型并返回新的对象类型,为此,我们需要使用 TypeScript 提供的映射类型。
映射类型的语法如下:
其中 P in K 类似于 JavaScript 中的??for...in
??语句,用于遍历类型 K 中的所有类型,而 T 类型变量用于表示 TypeScript 中的任何类型。
在介绍相关知识之后,让我们定义一个??MyOmit
??泛型。
type MyOmit<T, K extends keyof any> = {
[P in Exclude<keyof T, K>]: T[P]
}
在上面的代码中,?T
??和??K
??被称为类型参数。?keyof
??操作符用于获取一个类型中的所有键,其返回类型是一个联合类型。如果??keyof
??操作对象类型,则其功能类似于??Object.keys
??方法。
而?K extends keyof any
?是一个泛型约束,用于约束类型参数?K
?对应的实际类型是联合类型(?string | number | symbol
?)的子类型,?T[P]
?用于获取T类型中P属性对应的类型,其中类型变量P的值在遍历过程中会不断变化。
?Exclude
??泛型是 TypeScript 中的一个内置实用类型,它的角色是通过从??UnionType
??中排除所有可赋值给??ExcludedMembers
??的联合成员来构造一个类型。
事实上,?Exclude
??泛型的实现并不复杂,它在内部使用了条件类型。如果您对条件类型还不熟悉,可以阅读以下文章:
/**
* Exclude from T those types that are assignable to U.
* typescript/lib/lib.es5.d.ts
*/
type Exclude<T, U> = T extends U ? never : T;
为了更好地理解??Exclude
??泛型,让我们来看看它是如何工作的:
最后,让我们看一下完整的代码:
interface Todo {
title: string;
description: string;
completed: boolean;
}
type MyOmit<T, K extends keyof any> = {
[P in Exclude<keyof T, K>]: T[P];
};
type TodoPreview = MyOmit<Todo, "description" | "title">;
const todo: TodoPreview = {
completed: false,
};
这个挑战涉及到的主要知识是 TypeScript 的映射类型,如果你想了解更多关于映射类型的信息,可以阅读以下文章:
除了上面的实现,我们还可以使用??Pick
??泛型来实现??MyOmit
??泛型:
type MyOmit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
?欢迎关注公众号:文本魔术,了解更多