typescript - 如何在 Typescript 上对未知类型使用条件

标签 typescript typescript-generics

我在一个项目上有一个无类型函数,该函数在集合上执行异步函数,并且我想指定其类型以获得更好的 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

Playground link to code

关于typescript - 如何在 Typescript 上对未知类型使用条件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63745107/

相关文章:

TypeScript 泛型函数参数和返回类型推断

Typescript - 嵌套映射类型给出令人困惑的类型提示

javascript - 如何使用 Typescript 和 fetch 处理 204 状态?

javascript - @types/react 找不到名称 'HTMLDialogElement'

javascript - Ionic - 无法使用可变键推送对象

TypeScript:条件类型和使用 bool 参数来控制返回类型

typescript - 将 Type 约束为 T 的键并且为特定类型

reactjs - 接口(interface)命名约定(接口(interface)名称与组件名称冲突)

javascript - 如何将变量从@Input 传递到 Angular2 组件中的服务>

typescript - 在 TypeScript 中,如何获取值为给定类型的对象类型的键?