我嘗試撰寫以下 TypeScript 代碼,但它的作業原理引發了一些問題。它“有點”作業,因為構造"union"屬性的型別確實是記錄值的聯合。記錄鍵被忽略。
export type Unificator<T extends Record<string, unknown>> = { [P in keyof T as "union"]: T[P] }["union"];
let u: Unificator<{
a: { foo: "bar" },
b: { bar: "baz" },
c: { answer: 42 }
}>;
u = { foo: "bar" }; // Valid.
u = { bar: "baz" }; // Valid.
u = { answer: 42 }; // Valid.
前三個問題是:
- 這是對映射型別的合法使用還是我在做一些奇怪的事情?
- 有沒有更正統的方法將任意數量的型別聯合在一起?
- 如果上面的代碼確實是合法的,有沒有辦法避免臨時的“聯合”屬性?
但對我來說最重要的問題是另一個問題:
- 有沒有辦法“交叉”任意數量的型別?
我想做以下事情。
export type Intersector<T extends Record<string, unknown>> = /* HELP PLZ! */;
let i: Intersector<{
a: { foo: "bar" },
b: { bar: "baz" },
c: { answer: 42 }
}>;
i = {
foo: "bar",
bar: "baz",
answer: 42
}; // Valid.
uj5u.com熱心網友回復:
我們通常會這樣做:
type Unificator<T extends Record<string, unknown>> = T[keyof T];
你可以在這里找到一個小的解釋。
要將聯合的成員交叉在一起,我們必須拿出我們的 TypeScriptnomicon 并翻到第 50374908 頁:
type UnionToIntersection<U> =
(U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never
然后我們可以與之前的聯合相交:
type Intersector<T extends Record<string, unknown>> = UnionToIntersection<T[keyof T]>;
Record<string, unknown>此外,這兩個中都不需要通用約束,因此如果您愿意,可以省略它們。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/511207.html
標籤:打字稿仿制药
