Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

「重学TS 2.0 」TS 练习题第四十六题 #67

Open
semlinker opened this issue Oct 12, 2021 · 5 comments
Open

「重学TS 2.0 」TS 练习题第四十六题 #67

semlinker opened this issue Oct 12, 2021 · 5 comments

Comments

@semlinker
Copy link
Owner

实现 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
};

请在下面评论你的答案

@zhaoxiongfei
Copy link

zhaoxiongfei commented Oct 13, 2021

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 和 可选。

@s1pz
Copy link

s1pz commented Oct 22, 2021

秒啊,但是有个问题啊,partial会把值变成 never | undefined , 最终就是undefined。因此{
name: "lolo",
age: undefined
} 这样写也不会报错

@jackwangwj
Copy link

type RequireAllOrNone<T, K extends keyof T> = Omit<T, K> & ({
[P in K]-?: T[P]
} | {
[P in K]?: never
})

@dentm
Copy link

dentm commented Jun 24, 2022

type Readonly<T> = {
     readonly [P in keyof T] -?: T[P]
  }

  type RequireAllOrNone<T, K extends keyof T> = Readonly<Pick<T, K>> & Omit<T, K>
···

@zhengyimeng
Copy link

type RequireAllOrNone<T, K extends keyof T> =
  | (Omit<T, K> & Required<Pick<T, K>>)
  | { [Key in keyof T]: Key extends K ? never: T[Key] };

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants