我有一个 MyType 类型,看起来像这样
type MyType<V> {
value: V
}
我正在尝试实现一个函数,该函数接受各种 MyType 对象的元组,并返回值。
期望的行为:
const obj1 = {value:1}
const obj2 = {value: "hello"}
const obj3 = {value: new Date()}
const values = getValues(obj1, obj2, obj3)
// Need typescript to infer that values is of type [number, string, Date]
我的尝试(当我尝试在递归函数调用中返回空列表时出现错误):
type Infer<T> = T extends MyType<infer V> ? V : never;
type InferRecursive<T extends any[]> =
T extends [] ?
[] : T extends [infer U, ...infer URem] ?
[Infer<U>, ...InferRecursive<URem>]
: never;
function getValue<T extends MyType<any>>(obj: T): Infer<T> {
return obj.value;
}
function getValues<T extends MyType<any>[]>(...objs: T): InferRecursive<T> {
if (objs.length === 0) {
// *ERROR HERE* --> [] cannot be assigned to InferRecursive<T>
return [];
}
const [next, ...rest] = objs;
return [
getValue(next), ...getValues(...rest)
]
}
期望的行为:
const obj1 = {value:1}
const obj2 = {value: "hello"}
const obj3 = {value: new Date()}
const values = getValues(obj1, obj2, obj3)
// Need typescript to infer that values is of type [number, string, Date]
我的尝试(当我尝试在递归函数调用中返回空列表时出现错误):
type Infer<T> = T extends MyType<infer V> ? V : never;
type InferRecursive<T extends any[]> =
T extends [] ?
[] : T extends [infer U, ...infer URem] ?
[Infer<U>, ...InferRecursive<URem>]
: never;
function getValue<T extends MyType<any>>(obj: T): Infer<T> {
return obj.value;
}
function getValues<T extends MyType<any>[]>(...objs: T): InferRecursive<T> {
if (objs.length === 0) {
// *ERROR HERE* --> [] cannot be assigned to InferRecursive<T>
return [];
}
const [next, ...rest] = objs;
return [
getValue(next), ...getValues(...rest)
]
}
您遇到的 TypeScript 错误是因为 TypeScript 编译器无法使空数组 (
[]
) 的类型与预期返回类型 InferRecursive<T>
保持一致。由于函数中的 T
可以是 MyType<any>[]
的任何元组类型,因此当您指定 []
时,TypeScript 不会自动推断它与 T
可能代表的每种可能的元组结构兼容。
解决此问题的一种方法是将空数组显式转换为适当的类型。这是
getValues
函数的修改版本,应该可以工作:
type MyType<V> = {
value: V;
}
type Infer<T> = T extends MyType<infer V> ? V : never;
type InferRecursive<T extends any[]> =
T extends [] ? [] :
T extends [infer U, ...infer URem] ? [Infer<U>, ...InferRecursive<URem>] :
never;
function getValue<T extends MyType<any>>(obj: T): Infer<T> {
return obj.value;
}
function getValues<T extends MyType<any>[]>(...objs: T): InferRecursive<T> {
if (objs.length === 0) {
// Explicitly cast the empty array to the expected return type
return [] as InferRecursive<T>;
}
const [next, ...rest] = objs;
return [
getValue(next),
...getValues(...rest)
] as InferRecursive<T>;
}
此函数显式地将空数组
[]
转换为 InferRecursive<T>
以确保类型安全性和兼容性,允许 TypeScript 推断具有不同结构 MyType<any>
的元组的正确类型