我有一个数组对象,其中每个数组都是一对[value, function]
,其中function
在参数中接受value
:
const items = {
first: ['a', val => val.length], // val should be string
second: [[1, 2], val => val.push(3)] // val should be number[]
}
是否可以将函数参数(第二个数组项)的类型设置为与第一个数组项的类型相同?我创建了它,但是它不起作用(函数参数的类型始终未知):
type Items = {
[key: string]: any extends [infer Value, any] ? [Value, (val: Value) => any] : never
}
const items: Items = {
first: ['a', val => val.length], // val should be string, but is unknown
second: [[1, 2], val => val.push(3)] // val should by number[], but is unknown
}
答案 0 :(得分:0)
我建议这样做:
type Item<T> = [T, (val: T) => any]
const items = {
first: ['a', val => val.length] as Item<string>,
second: [[1, 2], val => val.push(3)] as Item<number[]>
}
在这种情况下,我使用了强制类型转换,因为您在同一对象中具有不同的类型,但是我认为您可以重新排列数据结构以避免强制类型转换。
答案 1 :(得分:0)
以下是hinosxz答案(Playground)的替代方法:
type Items = {
[K: string]: Item<any, unknown>
}
type Item<T, U> = [T, (t: T) => U]
const item = <T, U>(...args: Item<T, U>) => args // factory fn
const items: Items = {
first: item('a', val => val.length), // works
second: item([1, 2], val => val.push(3)), // works
third: item({}, val => val.length), // error (good)
fourth: item({ 0: 1 }, val => val.push(3)) // error (good)
}
对于index signature,所有属性值必须具有相同的类型。因此,您不能有效地使用泛型类型参数。
TS目前还缺乏类似correlated types的结构来表达,即属性键与其值 per 属性之间存在联系,而不是所有属性都存在。
要解决该问题,我们可以像往常一样显式键入所有属性(为简化起见,省略),也可以选择更广泛的Items
基本类型,并分别使用Item
类型和{{1} }如上所示的工厂功能。
您最好不要在这里使用type assertion,因为它的编译器检查比常规的赋值检查要宽松得多。例如item
和third
wouldn't trigger an error具有类型断言。