網站搜尋

在 TypeScript 類型中分組可選項


我有一個物件需要將某些可選項分組。因此,要麼不傳入任何項,要麼兩者都傳入。我通常會將這個加入到巢狀屬性中,但我無法更改這個物件的結構。

在下面的例子中,有一個必需的 'a',一個可選的 'b',但是 'c' 和 'd' 必須要麼都提供,要麼都不提供。

type Basic = {
 a: string,
 b? string, // independant

 c?: boolean, // if c is given, d must also be given
 d?: (e: boolean) => void, // if d is given, c must also be given 
}

我試著寫一些花俏的 Typescript,但看起來我還不夠好,無法理解進階的東西。

type GroupedOptional<T> = {
    [K in keyof T]: undefined;
} & Required<T>

type Fancy = {
 a: string,
 b?: string,
} & GroupedOptional<{
  c: boolean,
  d: (e: boolean) => void,
}>;

答案#1

這應該可行:

type AllOrNothing<T> = T | Partial<Record<keyof T, undefined>>

type Fancy = {
    a: string,
    b?: string,
} & AllOrNothing<{
    c: boolean,
    d: (e: boolean) => void,
}>;

let t1:Fancy =  { a: ""}
let t2:Fancy =  { a: "", c: true} // err
let t3:Fancy =  { a: "", c: true, d: (e)=> {}} // ok

全有或全無,會在原始的 T 與 Partial 之間創建一個聯合,這個聯合強制規定如果某些屬性存在,它們應該是 undefined(基本上就是禁止它們)