簡體   English   中英

如何在 Typescript 中用另一個對象的值派生一個對象類型?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM