我在一个项目上有一个无类型函数,该函数在集合上执行异步函数,并且我想指定其类型以获得更好的 IDE 帮助 - 我希望 IDE 推断回调时的第一个参数与数组内部类型相同.
这是函数:
export async function asyncForEach(array, callback) {
for (let index = 0; index < array.length; index++) {
await callback(array[index], index, array);
}
}
我添加了这样的明显类型,但出现了问题:
export async function asyncForEach<T>(
items: T[],
callback: (item: T, idx: number, items: T[]) => Promise<any>
): Promise<void> {
for (let index = 0; index < items.length; index += 1)
await callback(items[index], index, items);
}
之后我得到了下一个场景:
- 当第一个参数是类型化数组
[]时,第一个回调参数被正确推断为 - 当第一个参数是普通数组 [] 时,第一个回调参数被正确推断为 any
- 问题:当第一个参数是“any”类型变量时,第一个回调参数现在被推断为“未知”而不是“any” 回调参数类型推断的这种变化导致了遗留代码的一些构建问题,这些遗留代码很乐意访问“任何”变量的属性,但如果变量是“未知”,则会中断。
我希望能够在回调参数输入中指定一个三元组,这样如果它是“未知”,而不是“任何”。
这是我所做的几次尝试之一,但没有成功 - 编译器拒绝构建并且类型推断停止工作。
export async function asyncForEach<T>(
items: T[],
callback: (item: T extends unknown ? any: T, idx: number, items: T[]) => Promise<any>
): Promise<void> {
for (let index = 0; index < items.length; index += 1)
await callback(items[index], index, items);
}
有人知道如何解决(item: T extendsunknown ? any: T,
部分吗?
提前非常感谢。
最佳答案
我不知道你所做的是否可取;我的倾向是:如果有人故意传入不健全的 items
参数 any
无论在何处使用类型,都会关闭类型检查,他们必须处理后果。在这种情况下,结果是编译器不知道如何推断 T
,因此它默认为 unknown
( as of TypeScript 3.5 )。
如果您想让编译器选择不同的默认值,您可以specify one在类型参数声明中使用 =
运算符:
export async function asyncForEach<T = any>(
items: T[],
callback: (item: T, idx: number, items: T[]) => Promise<any>
): Promise<void> {
for (let index = 0; index < items.length; index += 1)
await callback(items[index], index, items);
}
请注意上面的T = any
。现在您会得到以下行为:
declare const a: any;
asyncForEach(a, async (i) => i.randomThingBecauseAnyDoesntTypeCheck); // okay
这就是您想要的,并且不会因类型更良好的项目
而失去所需的行为:
asyncForEach([a], async (i) => i.randomThingBecauseAnyDoesntTypeCheck); // okay
asyncForEach([1, 2, 3], async (i) => i.toFixed()); // okay
关于typescript - 如何在 Typescript 上对未知类型使用条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63745107/