![](/img/trans.png)
[英]Stricter typing of possible call signatures defined in interfaces in TypeScript
[英]How to enforce stricter typing on Maps and Sets in TypeScript?
如果我像这样创建 map:( 操场)
const x = new Map();
const y = x.get("foo");
y.thisDoesntExist();
我希望在最后一行出现错误(至少在严格模式下),因为我从未指定new Map
的键和值类型应该是什么。 相反,map 的类型是Map<any, any>
,所以我没有收到任何警告。 Set<any>
也是如此。
我正在移植一个 JavaScript 项目,所以像这样的案例到处都是,很难判断哪里缺少类型。
有没有办法配置 typescript 以便在我尝试在没有 generics 的情况下实例化集合和映射时警告我? 或者至少让 generics 默认为Set<unknown>
?
无参数Map
构造函数具有Map<any, any>
返回类型:
interface MapConstructor {
new(): Map<any, any>;
// ...
}
因此noImplicitAny
在这里没有帮助(类型是显式的)
可以做的是用Map<unknown, unknown>
覆盖它( 声明合并):
interface MapConstructor {
new(): Map<unknown, unknown>;
}
现在y.thisDoesntExist();
会报错。
Set
的行为不同,因为它的构造函数定义为:
new <T = any>(values?: readonly T[] | null): Set<T>;
因此,如果未提供泛型类型和值 - 类型将是unknown
的:
const s = new Set(); // s: Set<unknown>
更新(2022 年 6 月 28 日)
在使用 JavaScript + JSDoc 时,似乎简单地使用never
而不是unknown
就足以使类型变得严格。 不知道为什么我之前必须跳过这么多圈,但现在我只是在使用。
interface SetConstructor {
new(): Set<never>;
}
interface MapConstructor {
new(): Map<never, never>;
}
旧答案
要使用 JSDoc 在 js 中使用 ts,您可以在新的.d.ts
中添加以下内容
interface MapConstructor extends Omit<MapConstructor, 'new'> {
new<K = unknown, V = unknown>(entries?: readonly (readonly [K, V])[] | null): Map<K, V>;
}
interface SetConstructor {
new <T = unknown>(values?: readonly T[] | null): Set<T>;
}
在 JavaScript 中,generics 在未设置时默认为any
( #14907 ),因此您必须明确将其默认设置为unknown
。 因此,在使用 JavaScript 时,空构造函数不起作用。
MapConstructor
在lib.es2015.collection.d.ts
中有一个空的new(): Map<any, any>
条目。 因此,为了删除它,我们使用Omit<MapConstructor, 'new'>
。 然后我们可以指定已经存在的相同构造函数,除了显式unknown
作为默认值。
SetConstructor
没有空的new()
条目,但它确实有new <T = any>
,所以我们也必须用unknown
覆盖它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.