题目描述
实现一个通用的PartialByKeys<T, K>
,它接收两个类型参数T
和K
。
K
指定应设置为可选的T
的属性集。当没有提供K
时,它就和普通的Partial<T>
一样使所有属性都是可选的。
例如:
interface User {
name: string
age: number
address: string
}
type UserPartialName = PartialByKeys<User, 'name'> // { name?:string; age:number; address:string }
题解
// ============= Test Cases =============
import type { Equal, Expect } from './test-utils'
interface User {
name: string
age: number
address: string
}
interface UserPartialName {
name?: string
age: number
address: string
}
interface UserPartialNameAndAge {
name?: string
age?: number
address: string
}
type cases = [
Expect<Equal<PartialByKeys<User, 'name'>, UserPartialName>>,
Expect<Equal<PartialByKeys<User, 'name' | 'age'>, UserPartialNameAndAge>>,
Expect<Equal<PartialByKeys<User>, Partial<User>>>,
// @ts-expect-error
Expect<Equal<PartialByKeys<User, 'name' | 'unknown'>, UserPartialName>>,
]
// ============= Your Code Here =============
type MergeIntersection<T> = {
[P in keyof T]: T[P]
}
type PartialByKeys<
T,
K extends keyof T = keyof T
> =
MergeIntersection<
& Omit<T, K>
& Partial<Pick<T, K>>
>
类型操作
-
MergeIntersection<T>
:-
这个类型的作用是将一个交叉类型中的所有属性合并成一个单一的类型
-
{ [P in keyof T]: T[P] }
:遍历T
的所有键,将每个键的值类型提取出来,形成一个新的类型
-
-
PartialByKeys<T, K>
:-
K extends keyof T = keyof T
:K
是一个联合类型,表示要使哪些属性变为可选。如果没有提供K
,则默认为keyof T
,即所有属性都变为可选 -
Omit<T, K>
:从T
中排除K
指定的属性 -
Partial<Pick<T, K>>
:将T
中的K
指定的属性变为可选 -
Omit<T, K> & Partial<Pick<T, K>>
:将排除的属性和变为可选的属性合并 -
MergeIntersection<...>
:将合并后的交叉类型中的所有属性合并成一个单一的类型
-