![](/img/trans.png)
[英]How can I indicate to TS that each property on an argument should map onto a property on the return type?
[英]How to capture type argument of nested property and map it to something else
我真的不知道怎么問這個問題,所以我認為最好的方法是舉一個我想做的事的例子。 假設我有以下對象:
const obj = {
one: 'some string',
two: new Set<string>(),
};
現在我想編寫一個函數,該函數接受該對象並將Set
轉換為相同類型的Array
。
這是無類型的javascript實現:
const obj = { one: 'some string', two: new Set().add('one').add('two'), }; function convertToArrays(objWithSets) { return Object.entries(objWithSets).reduce((objectWithArrays, [key, value]) => { if (value instanceof Set) { objectWithArrays[key] = Array.from(value); } else { objectWithArrays[key] = value; } return objectWithArrays; }, {}); } console.log('converted', convertToArrays(obj));
如何正確輸入以上功能? 需要說明的是:它可以接受任何對象(不僅是一個,兩個示例),而且如果看到Set<T>
,則將其轉換為Array<T>
。
我知道這需要捕獲內部Set
的類型(在這種情況下為string
),並有條件地將該類型映射到Array<string>
。
謝謝!
您可以混合使用映射類型和條件類型來執行此操作:
type InnerSetToArray<T> = {
[P in keyof T]:
T[P] extends Set<infer U>
? Array<U>
: T[P]
};
type InnerSet = { one: number, two: Set<string>, three: Set<Function>, four: Date };
// InnerArray === { one: number, two: string[], three: Function[], four: Date }
type InnerArray = InnerSetToArray<InnerSet>;
編輯:以下是原始的,過於具體的答案:
正如您所描述的,我們開始了:
function convertToArrays<T extends { one: string, two: Set<any> }>(objWithSets: T):
T extends { one: string, two: Set<infer U> }
? { one: string, two: Array<U> }
: never {
/* ... */
}
// typeof x === { one: string, two: number[] }
const x = convertToArrays({ one: "hello", two: new Set([1, 2, 3]) })
我們允許它最初是Set<any>
只是為了用作類型保護,然后使用條件推斷實際類型。 條件會縮小到never
匹配失敗,這應該很好,因為從理論上來說,初始檢查可以確保條件始終為真。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.