如何让TypeScript中Set和Map在泛型未知时报错?
我早前写代码时发现一个差异:未指定泛型的Set和Map会被TypeScript推断为Set<unknown>和Map<unknown, unknown>,调用它们的方法(比如set.has(1)、map.has(1))完全不会触发类型错误;但未指定类型的数组const arr = []会被推断为any[],同时立刻触发隐式any的错误提示。示例代码如下:
const set = new Set(); set.has(1); const map = new Map(); map.has(1); const arr = []; // Variable 'arr' implicitly has type 'any[]' in some locations where its type cannot be determined. arr.includes(1); // Variable 'arr' implicitly has an 'any[]' type.
要让Set和Map在未指定泛型时也抛出错误,可以试试这些方法:
结合
noImplicitAny与自定义约束
TypeScript默认对无泛型的Set/Map推断为unknown而非any,所以noImplicitAny规则不会触发错误。你可以通过自定义工具类型,强制要求必须显式传入泛型参数,或者在代码中通过类型断言临时约束,让未指定泛型的写法直接报错。用ESLint自定义规则强化检查
原生TypeScript没有强制Set/Map必须指定泛型的内置规则,但可以借助ESLint编写自定义规则,检查new Set()或new Map()是否带有泛型参数,一旦发现无泛型的写法就抛出错误提示。临时用
never类型约束
如果只是在局部代码里想快速触发错误,可以显式把Set/Map的类型声明为Set<never>或Map<never, never>,后续调用任何添加元素的方法都会直接报错,以此提醒自己补充泛型:const set: Set<never> = new Set(); set.add(1); // 类型“number”的参数不能赋给类型“never”的参数严格模式+代码审查规范
开启TypeScript的strict模式能增强整体类型检查的严格度,再配合团队代码审查规范,要求所有Set/Map必须显式指定泛型,从流程上避免遗漏泛型的写法。
内容的提问来源于stack exchange,提问作者Leo Jiang

