![](/img/trans.png)
[英]Typescript generics: How to implicitly derive the type of a property of an object from another property of that object?
[英]How to derive an object type with another object's values in Typescript?
我正在嘗試創建一個函數,該函數將返回一個通用對象類型,其鍵是從傳遞給該函數的參數派生的。 一個簡化的例子:
// What do I put here for this to work?
type ObjectB<T> = {};
declare function makeObjectB<T>(a: T): ObjectB<T>;
const objectB = makeObjectB({
name: "foo"
});
console.log(objectB.foo)
typeof objectB
會導致類似:
{
foo: string
}
如果還支持以下示例,則加分:
// What do I put here for this to work?
type ObjectB<T> = {};
declare function makeObjectB<T>(a: T[]): ObjectB<T[]>;
const objectB = makeObjectB([{ name: "foo" }, { name: "bar" }]);
console.log(objectB.foo)
console.log(objectB.bar)
typeof objectB => { foo: string; bar: string }
當然可以,使用映射類型:
type ObjectB<T extends { name: string }> = {
[K in T["name"]]: string;
};
您會注意到T
之后的extends { name: string }
。 這是一個通用約束,類似於函數參數類型參數。
在映射類型中,我們遍歷T["name"]
中的每個K
並將其映射到string
。
因此,如果我們有這個: ObjectB<{ name: "foo" }>
, T["name"]
將是"foo"
並且這種類型將導致:
{
foo: string;
}
使用這種類型,我們現在可以編寫函數簽名:
declare function makeObjectB<T extends { name: string }>(a: T): ObjectB<T>;
您還會注意到這里存在相同的通用約束。 這是為了滿足 TypeScript 的要求,即makeObjectB
中的T
可以與ObjectB
一起使用。
對於獎勵積分,我們可以定義一個重載:
declare function makeObjectB<T extends ReadonlyArray<{ name: string }>>(a: T): ObjectB<T[number]>;
T
現在可以是具有指向字符串的name
鍵的任何對象數組。
這里不同的另一件事是使用ObjectB<T[number]>
而不僅僅是ObjectB<T>
。 這讓我們可以將數組中的所有元素(此處為元組)作為一個聯合,這意味着T["name"]
現在類似於"foo" | "bar"
"foo" | "bar"
。
您可以在此處嘗試此解決方案。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.