【发布时间】:2021-08-03 20:39:15
【问题描述】:
我有一个函数,它接受一个数组,并返回一个对象,其键是使用数组中的值设置的。
简化示例:
// arr will be an array of arrays of type [string] *or* [string, string]
function foo(arr) {
const output = {}
arr.forEach(value => {
// if this value has length 2, use the second string as the key
const key = value.length === 1 ? value[0] : value[1]
// always use the first string as the value
const value = value[0]
output[key] = value
})
return output
}
例如,运行foo([['a', 'orange'], ['b'], ['c', 'apple']) 将产生{ orange: 'a', b: 'b', apple: 'c' } 类型为{ orange: string, b: string, apple: string } - 我们称该类型为R - 请注意,我并不真正关心R 的值是文字。这将是一个不错的奖励,但更通用的 string 类型就足够了。
使用 Typescript,我想从输入 arr、T 的泛型推断 foo、R 的返回类型。
我可以像这样输入T
function foo<T extends Array<[string, string?]>(arr: T) { ... }
那么是否可以从T 推断出R?
更新
我可以看到的一个潜在问题是,这种运行违反了 Typescript 的能力限制,R 需要关心 T 的值的顺序,因为您当然可以指定重复的键。
即它不像类似的泛型对象类型那样纯粹-> 泛型对象类型映射语法[K in keyof T]: T[K] extends Thing ? ... : ...。
如果这是一个问题,但有可能绕过它并简单地忽略它,即仅在没有任何重复键的情况下使这种类型安全,这对我的用例来说很好。
【问题讨论】:
-
除非您声明数组
const,否则您不能。一般来说,Typescript 编译器不能从数组的元素中推断出类型(因为只有在运行时才能知道确切的元素)。 -
在调用代码中将数组声明为
const对我的用例来说很好!那么foo的返回类型声明中的语法是什么? -
不,这不起作用,因为函数参数不是
const,您可以使用 any 数组调用该函数。 -
@aleksxor 这太好了,谢谢!我已将支票交给@captain-yossarian,以便在没有
const的情况下设法做到这一点,但如果您将此添加为答案,我会投票赞成:-) -
@captain-yossarian 是真的,你的回答很棒。查看 OP 代码让我将参数视为动态数组(内置代码),而不是文字数组:我很确定这不会起作用。
标签: typescript