假設我有以下界面:
interface Person {
name: string;
age: number;
location: string;
}
我想將其擴展為具有 3 個附加屬性,一個用于每個介面的原始屬性。
所以我想要的最終結果是:
interface Person {
name: string;
nameHidden: boolean;
age: number;
ageHidden: boolean;
location: string;
locationHidden: boolean;
}
我正在通過 TypeScript 研究映射型別:https ://www.typescriptlang.org/docs/handbook/2/mapped-types.html
但我無法弄清楚如何實作這種行為。它僅顯示如何重新映射現有屬性的示例,而不是在現有屬性之上添加新屬性。
uj5u.com熱心網友回復:
你說過你不需要它是相同的界面。在這種情況下,您可以這樣做:
type WithFlags<T> = T & {
[Key in keyof T as Key extends string ? `${Key}Hidden` : never]: boolean;
};
type PersonWithFlags = WithFlags<Person>;
游樂場示例
這將創建一個新型別,該型別是傳入的型別T
加上其中每個屬性的屬性(至少是名稱為 extend 的屬性string
),并Hidden
添加到 name 和 typeboolean
中。
Titian Cernicova-Dragomir在評論中指出(謝謝!)& string
,我們可以通過使用更短一點的代替來避免該鍵映射中的條件:
type WithFlags<T> = T & {
[Key in keyof T & string as `${Key}Hidden`]: boolean;
// ????????????????^^^^^^^^^
};
游樂場鏈接
pilchard在評論中指出,該檔案幾乎有相同的示例。他們像提香一樣進行重新映射,但在不同的地方:
type WithFlags<T> = T & {
[Key in keyof T as `${Key & string}Hidden`]: boolean;
// ??????????????????????????^^^^^^^^^
};
游樂場鏈接
uj5u.com熱心網友回復:
我接受了T.J. Crowder
的答案并對其進行了一些修改,以使該型別更具(可重用)可使用性:
type WithFlags<T, TFlag extends string, TValue = null> = T & {
[Key in keyof T & string as `${Key}${TFlag}`]: TValue extends null ? T[Key] : TValue;
};
默認情況下,您必須傳遞介面和標志名稱,這會導致基于Person
介面和TFlag
=的以下型別Hidden
:
{
name: string;
age: number;
location: string;
nameHidden: string;
ageHidden: number;
locationHidden: string;
}
如果您希望附加屬性具有特定型別,例如boolean
您可以調整第三個型別引數TValue
。
為了滿足您的要求,您可以使用一個輔助型別,例如:
type WithHiddenFlags<T> = WithFlags<T, 'Hidden', boolean>;
結果WithHiddenFlags<Person>
型別是:
{
name: string;
age: number;
location: string;
nameHidden: boolean;
ageHidden: boolean;
locationHidden: boolean;
}
我看到的唯一限制是,對于TValue = null
,生成的屬性將具有原始屬性的型別,而不是null
.
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/517344.html