【发布时间】:2019-07-03 20:20:25
【问题描述】:
我正在尝试通过使用更严格的 lint 规则集来收紧我的 TS 代码,但我正在努力解决什么应该是合法的动态用途。
我正在制作一个类型保护来检测某些东西是否是可迭代的(如果不是,则将其包装在一个数组中),除了抑制 lint 规则以告诉它是 kosher 之外,我不知道要告诉 TS 什么:
function isIterable(obj: any): obj is Iterable<unknown> {
return obj && typeof obj[Symbol.iterator] === 'function';
}
我尝试将其更改为:
function isIterable(obj: undefined | {[Symbol.iterator]?: unknown}): obj is Iterable<unknown> {
return !!obj && typeof obj[Symbol.iterator] === 'function';
}
它编译时不使用any,但它没有用,因为我想将未知类型的值传递给它。
是否有一种“干净”的方式来表示“是的,我实际上想依靠 JS 返回 undefined 来访问对象上不存在的属性”?特别是。因为这是编写类型保护的重点。
【问题讨论】:
-
isIterable(obj: unknown): obj is Iterable<unknown>? -
@jcalz 在没有类型断言的情况下使用
unknown做任何事情都是不合法的。在不打开suppressImplicitAnyIndexErrors的情况下访问object上的任意属性也是不合法的;即使那样你也不能做 obj.foo,而且 linter 会抱怨 obj['foo']。 (它适用于 obj[Symbol.whatever],这是针对上述情况的一种解决方法,但不适用于我想通过字符串命名的键来缩小类型的其他人,即 'then' 用于承诺。) -
是的,我明白你现在在说什么了。
标签: typescript tslint