简体   繁体   English

如何在 Typescript 中用另一个对象的值派生一个对象类型?

[英]How to derive an object type with another object's values in Typescript?

I'm trying to create a function that will return a generic object type with keys that are derived from an argument passed into that function.我正在尝试创建一个函数,该函数将返回一个通用对象类型,其键是从传递给该函数的参数派生的。 A simplified example:一个简化的例子:

// 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 would result in something like: typeof objectB会导致类似:

{
  foo: string
}

Bonus points if the following example could also be supported:如果还支持以下示例,则加分:

// 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 }

Sure it is, with a mapped type:当然可以,使用映射类型:

type ObjectB<T extends { name: string }> = {
    [K in T["name"]]: string;
};

You will notice the extends { name: string } after T .您会注意到T之后的extends { name: string } This is a generic constraint, which is similar to a function parameter type argument.这是一个通用约束,类似于函数参数类型参数。

Inside the mapped type, we go through each K in T["name"] and map it to a string .在映射类型中,我们遍历T["name"]中的每个K并将其映射到string

So if we had this: ObjectB<{ name: "foo" }> , T["name"] would be "foo" and this type would result in:因此,如果我们有这个: ObjectB<{ name: "foo" }>T["name"]将是"foo"并且这种类型将导致:

{
    foo: string;
}

With this type, we can write our function signature now:使用这种类型,我们现在可以编写函数签名:

declare function makeObjectB<T extends { name: string }>(a: T): ObjectB<T>;

You will also notice that the same generic constraint is present here.您还会注意到这里存在相同的通用约束。 This is to satisfy TypeScript that T from makeObjectB can be used with ObjectB .这是为了满足 TypeScript 的要求,即makeObjectB中的T可以与ObjectB一起使用。

And for bonus points, we can define an overload:对于奖励积分,我们可以定义一个重载:

declare function makeObjectB<T extends ReadonlyArray<{ name: string }>>(a: T): ObjectB<T[number]>;

T can now be any array of objects that have a name key that points to a string. T现在可以是具有指向字符串的name键的任何对象数组。

The other thing that's different here is using ObjectB<T[number]> instead of just ObjectB<T> .这里不同的另一件事是使用ObjectB<T[number]>而不仅仅是ObjectB<T> This lets us get all the elements in the array (technically tuple here) as a union, which means T["name"] is now something like "foo" | "bar"这让我们可以将数组中的所有元素(此处为元组)作为一个联合,这意味着T["name"]现在类似于"foo" | "bar" "foo" | "bar" . "foo" | "bar"

You can try this solution out here .您可以在此处尝试此解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 打字稿泛型:如何从该对象的另一个属性隐式派生该对象的属性的类型? - Typescript generics: How to implicitly derive the type of a property of an object from another property of that object? Typescript - 从联合或数组派生对象类型 - Typescript - derive object type from union or array 如何从键中导出 Typescript 类型的值 - How to derive the values of a Typescript type from the keys 使用通用类型从另一个对象的值派生的 Typescript 中创建一个 object 类型 - Create an object type in Typescript derived from another object's values using a generic type TypeScript:能够从 const object 文字推断/导出类型值,嵌套有非唯一键 - TypeScript: Ability to infer/derive values for type from const object literal, nested with non-unique keys 如何在打字稿中将一个对象的动态值添加到另一个不同类型的对象 - How to add dynamic values from one object to another object of different type in typescript 如何在打字稿中获取对象值作为类型? - How to get object values as type in typescript? TypeScript 如何键入 object 值作为字符串或函数 - TypeScript how to type an object with values as string or funcion 如何将任何类型值的 object 转换为字符串值的 object (Typescript)? - How to convert object of any type values, to object of string values (Typescript)? TypeScript:如何根据另一个对象的类型有条件地创建一个类型所需的属性? - TypeScript: How to conditionally make properties required in a type, based on another object's type?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM