awesome-typescript
awesome-typescript copied to clipboard
「重学TS 2.0 」TS 练习题第四十六题
实现 RequireAllOrNone
工具类型,用于满足以下功能。即当设置 age
属性时,gender
属性也会变成必填。具体的使用示例如下所示:
interface Person {
name: string;
age?: number;
gender?: number;
}
type RequireAllOrNone<T, K extends keyof T> = // 你的实现代码
const p1: RequireAllOrNone<Person, 'age' | 'gender'> = {
name: "lolo"
};
const p2: RequireAllOrNone<Person, 'age' | 'gender'> = {
name: "lolo",
age: 7,
gender: 1
};
请在下面评论你的答案
interface Person {
name: string;
age?: number;
gender?: number;
}
type RequireAllOrNone<T, K extends keyof T> = Omit<T, K> & (Required<Pick<T, K>> | Partial<Record<K, never>>)
const p1: RequireAllOrNone<Person, "age" | "gender"> = {
name: "lolo"
};
const p2: RequireAllOrNone<Person, "age" | "gender"> = {
name: "lolo",
age: 7,
gender: 1
};
const p3: RequireAllOrNone<Person, "age" | "gender"> = {
// const p3: SetRequired<Person, "age" | "gender"> = {
// const p3: Omit<Person, "age" | "gender"> = {
name: "lolo",
age: 7,
};
思路: 巧妙利用 never 和 可选。
秒啊,但是有个问题啊,partial会把值变成 never | undefined , 最终就是undefined。因此{ name: "lolo", age: undefined } 这样写也不会报错
type RequireAllOrNone<T, K extends keyof T> = Omit<T, K> & ({ [P in K]-?: T[P] } | { [P in K]?: never })
type Readonly<T> = {
readonly [P in keyof T] -?: T[P]
}
type RequireAllOrNone<T, K extends keyof T> = Readonly<Pick<T, K>> & Omit<T, K>
···
type RequireAllOrNone<T, K extends keyof T> =
| (Omit<T, K> & Required<Pick<T, K>>)
| { [Key in keyof T]: Key extends K ? never: T[Key] };