-
Notifications
You must be signed in to change notification settings - Fork 391
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 练习题第四十七题 #68
Comments
interface Person {
name: string;
age?: number;
gender?: number;
income?: number;
}
// 只能包含Keys中唯一的一个Key
type RequireExactlyOne<T, Keys extends keyof T, K extends keyof T = Keys> = Keys extends any
? Omit<T, K> & Required<Pick<T, Keys>> & Partial<Record<Exclude<K, Keys>, never>>
: never;
type T1 = RequireExactlyOne<Person, "age" | "gender" | "income">;
const p1: T1 = {
name: "lolo",
age: 7,
};
const p2: T1 = {
name: "lolo",
gender: 1
};
const p3: T1 = {
name: "lolo",
income: 100
};
// Error
const p4: T1 = {
name: "lolo",
age: 7,
gender: 1,
};
const p5: T1 = {
name: "lolo",
age: 7,
income: 1,
};
const p6: T1 = {
name: "lolo",
gender: 7,
income: 1,
};
const p7: T1 = {
name: "lolo",
age: 8,
gender: 7,
income: 1,
}; 解题思路: 利用联合类型 extends 实现分布执行,之后重点是 如何让联合类型规则只有其中某一个生效,在每一个上设置哪些禁止的属性为可选 never |
interface Person1 {
name: string;
age?: number;
gender?: number;
}
// 想要构建成这个样子才可以满足条件
type ttt = { name: string } & ({ age: number, gender?: never } | { age?: never, gender: number })
type RP<T, K> = {
[P in keyof T]: P extends K ? T & Partial<Record<P, never>> : never
}[keyof T];
// 只能包含Keys中唯一的一个Key
type RequireExactlyOne<T, K extends keyof T> = Omit<T, K> & RP<Pick<T, K>, K>
const p1: RequireExactlyOne<Person1, 'age' | 'gender'> = {
name: "lolo",
age: 7,
};
const p2: RequireExactlyOne<Person1, 'age' | 'gender'> = {
name: "lolo",
gender: 1
};
// Error
const p3: RequireExactlyOne<Person1, 'age' | 'gender'> = {
name: "lolo",
age: 7,
gender: 1
}; |
type RequireExactlyOne<T, K extends keyof T> = K extends any
? Omit<T, K> & Partial<Record<K, never>>
: never; |
type RequireExactlyOne<T, Keys extends keyof T, K extends keyof T = Keys> =
Omit<T, K> & Partial<Record<K, never>> | (
Keys extends any
? Omit<T, K> & Required<Pick<T, Keys>> & Partial<Record<Exclude<K, Keys>, never>>
: never
)
|
type RequireExactlyOne<T, K extends keyof T, W extends keyof T = K> = Omit<T, W> & (
K extends any ? Required<Pick<T, K>> & Partial<Record<Exclude<W, K>, undefined>> : 1
) |
// 只能包含Keys中唯一的一个Key
type RequireExactlyOne<T, Keys extends keyof T> = Keys extends any
? Omit<T, Keys> & { [K in Keys]: never }
: never; 为啥这样不对呢? |
// 只能包含Keys中唯一的一个Key
type RequireExactlyOne<T, Keys extends keyof T> = Keys extends any
? Omit<T, Keys> & { [K in Keys]?: never }
: never; 抱歉少了一个 可选 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
实现
RequireExactlyOne
工具类型,用于满足以下功能。即只能包含age
或gender
属性,不能同时包含这两个属性。具体的使用示例如下所示:The text was updated successfully, but these errors were encountered: