[英]Type for a function that receives an array and returns a single element of that array?
[英]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转为数组。 之后它被过滤以包含一个没有未定义值的数组。 因此,我使用了两个辅助方法isAssigned
和isNil
。 请参阅此 CodeSandbox 示例: Code SandBox
根据您的担心,IE11 不支持 Object.value 方法,您可以为该方法添加一个 polyfill。 通过粘贴 polyfill 或使用 npm 将其添加到您的项目中。 或者,您可以将此代码替换为以下答案使用 Object.keys 来模仿 Object.values
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.