繁体   English   中英

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[]`

我有一些包含数据库文档的对象,我经常需要将它们转换为 arrays。

例子:

const MY_OBJECT = {
  docId_1: {...doc1},
  docId_2: {...doc2},
  docId_3: {...doc3},
  // AND SO ON
}

我需要将它转换成这样的数组:

const MY_ARRAY_FROM_OBJECT = [
  {...doc1}, 
  {...doc2}, 
  {...doc3},
  // AND SO ON...
]

这是我用来进行转换的代码:

function buildArrayFromObject(obj) {
  const keys = Object.keys(obj);
  const arr = [];
  for (const key of keys) {
    arr.push(obj[key]);
  }
  return arr;
}

我需要输入 function 以便我可以将它用于具有以下类型的对象:

interface BLOGPOSTS_ALL {
  [key: string]: BLOGPOST
}

interface PRODUCTS_ALL {
  [key: string]: PRODUCT
}

因此,当我用每个不同的 object 调用它们时,我希望 Typescript 知道返回数组类型是什么。

例如:

const BLOGPOSTS_ALL_ARRAY = buildArrayFromObject(BLOGPOSTS_ALL);  // SHOULD BE "BLOGPOST[]"
const PRODUCTS_ALL_ARRAY = buildArrayFromObject(PRODUCTS_ALL);    // SHOULD BE "PRODUCT[]"

这是我尝试过的:

function buildArrayFromObject<T, K extends keyof T>(obj: T): T[K][] {
  const keys = Object.keys(obj);
  const arr = [];
  for (const key of keys) {
    arr.push(obj[key]);
  }
  return arr;
}

但我收到此错误:

在此处输入图像描述

function 的返回类型被 Typescript 评估为never[]类型

你可以做的是:

创建一个抽象类型来定义你的数据库处理的样子:

// Create an Entity type to define how your database objects look like
type Entities<T> = { [key: string]: T | undefined }

因此,您可以这样表达您的产品和博文:

type BLOGPOSTS = Entities<BLOGPOST>;
type PRODUCTS = Entities<PRODUCT>;

为了以类型安全的方式将它们转换为数组,您可以使用Object.values方法 - 有关更多信息,请参阅MDN

可以用这样的方法替换buildArrayFromObject方法:

const isNil = <T>(a: T | null | undefined): a is null | undefined => a === null || a === undefined;
const isAssigned = <T>(a: T | null | undefined): a is T => !isNil(a);
const entitiesToArray = <T>(entity: Entities<T>): T[] => Object.values(entity).filter(isAssigned);

该方法使用Object.values方法将object转为数组。 之后它被过滤以包含一个没有未定义值的数组。 因此,我使用了两个辅助方法isAssignedisNil 请参阅此 CodeSandbox 示例: Code SandBox

根据您的担心,IE11 不支持 Object.value 方法,您可以为该方法添加一个 polyfill。 通过粘贴 polyfill 或使用 npm 将其添加到您的项目中。 或者,您可以将此代码替换为以下答案使用 Object.keys 来模仿 Object.values

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM