简体   繁体   English

TypeScript 和类型安全的 array.reduce

[英]TypeScript and type-safe array.reduce

I'm using the Array reduce function to create a keyed object representation of an array.我正在使用 Array reduce函数来创建一个数组的键控对象表示。 I have a working solution already, but noticed there are multiple ways to ensure the output object is type-safe.我已经有了一个可行的解决方案,但注意到有多种方法可以确保输出对象是类型安全的。

Given that I have the following interface and array:鉴于我有以下接口和数组:

interface Meta {
  name: string;
  value: string;
}

const metaArr: Meta[] = [
  { name: 'a', value: 'hello' },
  { name: 'b', value: 'hi' }
];

Out of the following three solutions, are any of them generally preferred, or is there a better way to do this?在以下三种解决方案中,通常首选其中的任何一种,还是有更好的方法来做到这一点?

  1. Use Record when declaring the reduce function:声明reduce函数时使用Record
const metaObj = metaArr.reduce<Record<string, Meta>>((acc, curr) => {
  acc[curr.name] = curr;
  return acc;
}, {});
  1. Declare dynamic keys mapped to the Meta interface for the initial object:为初始对象声明映射到Meta接口的动态键:
const metaObj = metaArr.reduce((acc, curr) => {
  acc[curr.name] = curr;
  return acc;
}, {} as { [key: string]: Meta });
  1. Use Record to cast the initial object:使用Record来转换初始对象:
const metaObj = metaArr.reduce((acc, curr) => {
  acc[curr.name] = curr;
  return acc;
}, {} as Record<string, Meta>);

Thanks in advance.提前致谢。

Although this may be a trivial example there are some opinionated considerations to be discussed.虽然这可能是一个微不足道的例子,但仍有一些观点需要讨论。 Preferring one representation over the other is inherently subjective.偏爱一种表示而不是另一种表示本质上是主观的。 Each solution functionally achieves the exact same result as any other, and the "testability" of each are also equivalent.每个解决方案在功能上实现与任何其他解决方案完全相同的结果,并且每个解决方案的“可测试性”也是等效的。

So based on your code, here are some things I may think about in order to help me with similar decisions:因此,根据您的代码,为了帮助我做出类似的决定,我可能会考虑以下一些事项:

  • reduce<Record<string, Meta>> is one of the first things you see when reading the code and without having scroll a potentially large reduce projection, it is clear the shape it will produce. reduce<Record<string, Meta>>是您在阅读代码时首先看到的内容之一,并且无需滚动可能较大的缩减投影,很明显它将产生的形状。
  • { [key: string]: Meta } is generally not as readable as the first point type declarations using Record<T, R> and there's more to write to achieve the same goal { [key: string]: Meta }通常不像使用Record<T, R>的第一个点类型声明那样可读,为了达到同样的目标还有更多的东西要写
  • {} as Record<string, Meta> : using as "assertions" is by no means a code smell, but referring to the first point again, readers of your code will need to look for the resultant type of the reduce by going to the bottom of the function {} as Record<string, Meta>as “断言”绝不是一种代码味道,但再次参考第一点,您的代码的读者将需要通过转到函数底部

Usually when faced with these kinds of questions, all roads lead to the readability of your code.通常当面对这些类型的问题时,所有的方法都会导致代码的可读性。 And while readability is also inherently a subjective pursuit, the more explicit and contained things are, generally, the easier it is to infer what a block of code is attempting to do.虽然可读性本质上也是一种主观追求,但通常越明确和包含的东西越容易推断代码块试图做什么。

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

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