yunliuyan / type-challenges

typescript-challenges
0 stars 2 forks source link

00029-medium-requiredbykeys #29

Open yunliuyan opened 11 months ago

yunliuyan commented 11 months ago

RequiredByKeys 中等 #object

by jiangshan @jiangshanmeta

接受挑战    English

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

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

例如:

interface User {
  name?: string
  age?: number
  address?: string
}

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

返回首页 分享你的解答 查看解答
yunliuyan commented 11 months ago

思路

用辅助pick和omit做辅助函数

代码实现

interface User {
  name?: string
  age?: number
  address?: string
}

type RequiredByKeys<T extends object, U extends keyof T> = Omit<T, U> & Required<Pick<T, U>>

type UserRequiredName = RequiredByKeys<User, 'name'> // { name: string; age?: number; address?: string
Naparte commented 11 months ago

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

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

type RequiredByKeys<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>;

interface User {
    name?: string
    age?: number
    address?: string
}

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

const uq: UserRequiredName = {
    name: '10',
    age: 9,
}
Janice-Fan commented 10 months ago
type RequiredByKeys<T, P extends keyof T> = {
    [k in keyof T as k extends P ? k : never]-?: T[k];
} & {
    [k in keyof T as k extends P ? never : k]: T[k];
} extends infer I ? { 
    [p in keyof I]: I[p]
} : never

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