简体   繁体   English

获取类型为“{ [key: string]: TYPE_X }”的对象并需要返回“TYPE_X[]”数组的函数的类型

[英]Type for a function that gets an object of type "{ [key: string]: TYPE_X }" and needs to return an array of "TYPE_X[]"

This is the code:这是代码:

Typescript playground 打字稿游乐场

interface TYPE_1 { foo1: "bar1" }
interface TYPE_2 { foo2: "bar2" }

interface OBJECT_1 {
    [key: string]: TYPE_1
}

interface OBJECT_2 {
    [key: string]: TYPE_2
}

type ARRAY_1 = TYPE_1[];
type ARRAY_2 = TYPE_2[];

type OBJ_IN = OBJECT_1 | OBJECT_2
type ARRAY_OUT = ARRAY_1 | ARRAY_2

function buildArrayFromObject(obj: OBJECT_1): ARRAY_1
function buildArrayFromObject(obj: OBJECT_2): ARRAY_2
function buildArrayFromObject(obj: OBJ_IN): ARRAY_OUT {
  const arr = [] as ARRAY_OUT;
  for (const item in obj) {
    arr.push(obj[item]);
  }
  return arr;
}

const obj1: OBJECT_1 = { id1: {foo1: "bar1" }, id2: {foo1: "bar1"}};
const obj2: OBJECT_2 = { id1: {foo2: "bar2" }, id2: {foo2: "bar2"}};

const array1 = buildArrayFromObject(obj1);
const array2 = buildArrayFromObject(obj2);

This is the error I'm getting:这是我得到的错误:

在此处输入图片说明

在此处输入图片说明

This code needs to accomplish the following:这段代码需要完成以下工作:

  • Take an object of type { [key: string]: TYPE_X } and return an array of TYPE_X[]取一个类型为{ [key: string]: TYPE_X }并返回一个TYPE_X[]数组

QUESTION

JS-wise the code is doing what it needs to. JS-wise 代码正在做它需要做的事情。 But Typescript is complaining about the types that are going into the array.但是 Typescript 抱怨进入数组的类型。 What am I doing wrong?我究竟做错了什么? How can I fix it?我该如何解决?

Problem问题

With this sort of overload structure there's no relationship between the "in" and the "out."在这种重载结构中,“输入”和“输出”之间没有关系。 You're trying to declare that the array elements much match the expected "out" type with as ARRAY_OUT , but you don't actually know what the expected type is.您试图声明数组元素与预期的“out”类型与as ARRAY_OUT非常匹配,但您实际上并不知道预期的类型是什么。 Recall that ARRAY_OUT is just an alias for ARRAY_1 | ARRAY_2回想一下, ARRAY_OUT只是ARRAY_OUT的别名ARRAY_1 | ARRAY_2 ARRAY_1 | ARRAY_2 . ARRAY_1 | ARRAY_2 So when you write:所以当你写:

const arr = [] as ARRAY_OUT;

You're saying that this array is either ARRAY_1 or ARRAY_2 .你说,这阵或者ARRAY_1ARRAY_2

The only way you can safely push to a union of two array types is if the value that you are adding could go in both array types, ie.您可以安全地push送到两个数组类型的联合的唯一方法是,您添加的值是否可以同时包含在两种数组类型中,即。 it must be TYPE_1 & TYPE_2 .它必须是TYPE_1 & TYPE_2

But the value that you get from your object is of either TYPE_1 | TYPE_2但是您从对象中获得的值TYPE_1 | TYPE_2 TYPE_1 | TYPE_2 and you don't know which. TYPE_1 | TYPE_2 ,你不知道是哪个。 So you get the error "Argument of type 'TYPE_1 | TYPE_2' is not assignable to parameter of type 'TYPE_1 & TYPE_2'"所以你得到错误“类型'TYPE_1 | TYPE_2'的参数不能分配给类型'TYPE_1 & TYPE_2'的参数”

Solution解决方案

We can use generics so that the function understands the pairing between "in" and "out" values.我们可以使用泛型,以便函数理解“输入”和“输出”值之间的配对。 Instead of defining ARRAY_OUT as a union, define it as a generic with depends on the value of the input object.不是将ARRAY_OUT定义为联合,而是将其定义为泛型,取决于输入对象的值。

We know that the returned array is an array whose elements are the values of the input object:我们知道返回的数组是一个数组,其元素是输入对象的值:

type Values<T> = T[keyof T];

type ARRAY_OUT<T> = Values<T>[];

So the function becomes:所以函数变成:

function buildArrayFromObject<T extends OBJ_IN>(obj: T): ARRAY_OUT<T> {
  const arr = [] as ARRAY_OUT<T>;
  for (const item in obj) {
    arr.push(obj[item]);
  }
  return arr;
}

(note: ARRAY_OUT<T> is the same as (T[keyof T])[] and you can use either one as your return type ) (注意: ARRAY_OUT<T>(T[keyof T])[] ,您可以使用任一作为返回类型)

The reason this works while the overloads didn't is because T is the same for both the "in" and "out".这有效而重载无效的原因是因为“输入”和“输出”的T相同。

Typescript Playground Link 打字稿游乐场链接

With the help of @Linda's answer, this is what I've come up with:在@Linda 的回答的帮助下,这就是我想出的:

type GENERIC_OBJECT<T> = {
  [key: string] : T
}

export function buildArray<T>(obj: GENERIC_OBJECT<T>) : T[] {
  const arr = [];
  for (const item in obj) {
    arr.push(obj[item]);
  }
  return arr;
}

暂无
暂无

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

相关问题 function 的类型接收类型为“[key: string]: SOME_TYPE”的 object 并返回类型为“SOME_TYPE[]”的数组 - Types for a function that receives an object of type `[key: string]: SOME_TYPE` and returns an array of type `SOME_TYPE[]` 类型“LodashReplace1x5”不可分配给类型“字符串” - Type 'LodashReplace1x5' is not assignable to type 'string' 类型“ X”的参数不能分配给类型“字符串”的参数 - Argument of type 'X' is not assignable to parameter of type 'string' 如何键入需要返回对象副本同时更改其属性之一的类型的函数? - How to type a function that needs to return a copy of an object while also changing the type of one of its properties? X 不可分配给“字符串”类型的参数 - X is not assignable to parameter of type 'string' 如何将 object 的数组传递给组件,类型 x 不可分配给类型“IntrinsicAttributes &amp; x” - how to pass array of object into component, Type x is not assignable to type 'IntrinsicAttributes & x' 引用带点符号的键,类型为{[x:字符串]:字符串} - Refer to a key with dot notation, type is { [x: string]: string} 推断数组对象的键类型 - Infer the key type of the array object Typescript:- 使用 object 为 function 创建泛型类型,其中一个键作为值类型,返回类型是值 - Typescript :- create generic type for function taking object having one key as type of value and return type is value “X”类型的参数不能分配给“X”类型的参数 - Argument of type 'X' is not assignable to parameter of type 'X'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM