跳到主要内容

RequiredByKeys

介绍

实现一个通用的RequiredByKeys<T, K>,它接收两个类型参数TK

K指定应设为必选的T的属性集。当没有提供K时,它就和普通的Required<T>一样使所有的属性成为必选的。

ts
interface User {
name?: string
age?: number
address?: string
}
type UserRequiredName = RequiredByKeys<User, 'name'> // { name: string; age?: number; address?: string }
ts
interface User {
name?: string
age?: number
address?: string
}
type UserRequiredName = RequiredByKeys<User, 'name'> // { name: string; age?: number; address?: string }
View on GitHub

起点

ts
/* _____________ Your Code Here _____________ */
 
type RequiredByKeys<T, K> = any
 
/* _____________ Test Cases _____________ */
 
interface User {
name?: string
age?: number
address?: string
}
 
interface UserRequiredName {
name: string
age?: number
address?: string
}
 
interface UserRequiredNameAndAge {
name: string
age: number
address?: string
}
 
type cases = [
Expect<Equal<RequiredByKeys<User, 'name'>, UserRequiredName>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<RequiredByKeys<User, 'name' | 'age'>, UserRequiredNameAndAge>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<RequiredByKeys<User>, Required<User>>>,
Type 'false' does not satisfy the constraint 'true'.
Generic type 'RequiredByKeys' requires 2 type argument(s).
2344
2314
Type 'false' does not satisfy the constraint 'true'.
Generic type 'RequiredByKeys' requires 2 type argument(s).
// @ts-expect-error
Expect<Equal<RequiredByKeys<User, 'name' | 'unknown'>, UserRequiredName>>,
]
 
ts
/* _____________ Your Code Here _____________ */
 
type RequiredByKeys<T, K> = any
 
/* _____________ Test Cases _____________ */
 
interface User {
name?: string
age?: number
address?: string
}
 
interface UserRequiredName {
name: string
age?: number
address?: string
}
 
interface UserRequiredNameAndAge {
name: string
age: number
address?: string
}
 
type cases = [
Expect<Equal<RequiredByKeys<User, 'name'>, UserRequiredName>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<RequiredByKeys<User, 'name' | 'age'>, UserRequiredNameAndAge>>,
Type 'false' does not satisfy the constraint 'true'.2344Type 'false' does not satisfy the constraint 'true'.
Expect<Equal<RequiredByKeys<User>, Required<User>>>,
Type 'false' does not satisfy the constraint 'true'.
Generic type 'RequiredByKeys' requires 2 type argument(s).
2344
2314
Type 'false' does not satisfy the constraint 'true'.
Generic type 'RequiredByKeys' requires 2 type argument(s).
// @ts-expect-error
Expect<Equal<RequiredByKeys<User, 'name' | 'unknown'>, UserRequiredName>>,
]
 
take the challenge

解决方案

Spoiler warning // Click to reveal answer
ts
// most popular
type RequiredByKeys<
T,
K extends keyof T = keyof T,
O = Omit<T, K> & { [P in K]-?: T[P] }
> = { [P in keyof O]: O[P] }
 
 
ts
// most popular
type RequiredByKeys<
T,
K extends keyof T = keyof T,
O = Omit<T, K> & { [P in K]-?: T[P] }
> = { [P in keyof O]: O[P] }
 
 
ts
// 按照PartialByKeys的思路
type RequiredByKeys<T, K extends keyof T = keyof T> =Omit< {
[P in keyof T as P extends K ? P : never]-?: T[P]
} & Omit<T, K>, never>
 
ts
// 按照PartialByKeys的思路
type RequiredByKeys<T, K extends keyof T = keyof T> =Omit< {
[P in keyof T as P extends K ? P : never]-?: T[P]
} & Omit<T, K>, never>
 
view more solutions