搜索词
重构
建议
提供一个将命名元组转换为对象字面量类型的重构。
使用场景
现在我们有命名元组。
编写元组以传递多个值是很常见的。
随着时间的推移,您可能会向元组中添加许多其他字段。
您不能在元组的中间或末尾取子序列。
如果我们能将其转换为对象,那将会很有用。
示例
type Tuple = [number, number]
function aggregate(items: number[]): Tuple {
// ...
return [min, max]
}
const [ min, max ] = aggregate(items)
增长到
type Tuple = [number, number, number, number, number, number]
function aggregate(items: number[]): Tuple {
// ...
return [min, max, avg, mid, first, last]
}
const [ min, max, avg, mid, first, last ] = aggregate(items)
如果我们只想获取第一个和最后一个
const [ , , , , first, last ] = aggregate(items) // too many '.'
const result = aggregate(items);
const first = result[4] // magic number
const last = result[5] // magic number
如果我们有这个重构
// add names into tuple
type Tuple = [min: number, max: number, avg: number, mid: number, first: number, last: number]
// apply refactor
type Tuple = {min: number, max: number, avg: number, mid: number, first: number, last: number}
function aggregate(items: number[]): Tuple {
// ...
return {min, max, avg, mid, first, last}
}
const { first, last } = aggregate(items)
检查清单
我的建议满足以下准则:
- 这不会对现有的TypeScript/JavaScript代码造成破坏性变化
- 这不会改变现有JavaScript代码的运行时行为
- 我们可以在不根据表达式的类型发出不同的JS的情况下实现这一点
- 这不是一个运行时特性(例如库功能、带有JavaScript输出的非ECMAScript语法等)
- 这个特性将与 TypeScript's Design Goals 的其他部分保持一致。
9条答案
按热度按时间uwopmtnx1#
此外,数组解构在底层通过调用
[Symbol.iterator]()
使用for‑of
,而对象解构则使用简单的[[Get]]
操作。z18hc3ub2#
一个好的解决方案可能取决于元组标签访问的内在效用类型。
可以像这样执行Map:
yx2lnoni3#
看起来这和type-level documentation问题非常相似,因为我们可能想要解包、附加和替换标签,即使它们没有相应的JS值(就像文档一样)。
一个内在的
Labeled
类型,可以同时附加和解包标签,在我看来最有意义。@tjjfvi,对此有什么想法吗?1mrurvl14#
内在的
Labeled
类型在我看来似乎有些奇怪,因为标签是元组的一个方面,而不是元素。或许更合理的做法是使用实用类型LabeledTuple<[A, B, C], ["a", "b", "c"]> = [a: A, b: B, c: C]
,可以像这样使用:话虽如此,虽然
LabeledTuple
实用类型很好,但我认为TupleToObject
类型并没有完全解决这个问题的使用案例,因为它不会改变数组解构为对象解构。关于原始问题,一个考虑因素是
[a: 1, a: 1]
是有效的,所以那些元组必须被排除或者特殊处理。dohp0rv55#
关于
LabeledTuple
的讨论:另请参阅 #44939gj3fmq9x6#
另一个用例是
Parameters<fn>
实用程序调用 - 它返回一个命名元组,但偶尔我想将一长串参数(对于库来说超出了我的控制范围)转换为 Package 器对象 - 如果我能为TupleToObject<Parameters<fn>>
做额外的一个 Package 器,那么这将稍微简化类型,并确保如果参数发生变化时它们始终正确(尽管目前它们可能会发生变化,但类型可能没有变化到足以触发编译器警告的程度)。vc9ivgsu7#
@Rycochet说了什么?👍
9njqaruj8#
+1 这仍然非常有帮助-我有一个案例,我想从Parameters<>中获取一个对象类型。
对此有任何进展吗?
8cdiaqws9#
请确认,目前没有解决这个问题的临时方法吗?这使得
Parameter<T>
的使用变得有些困难。类似于
{ [K in Exclude<keyof P, keyof any[]>]: P[K] }
的功能只是给出索引。即使有类似
labelof
的功能或者能提供很大帮助的东西。