typescript - 为什么类型谓词的类型必须可以分配给它的参数类型?
问题描述
我有一个类型谓词:
// tslint:disable-next-line:no-any
const isString = (value: any): value is string {
return typeof value === 'string'
}
这可行,但它要求我禁用我的 linter。我宁愿这样做:
const isString = <T>(value: T): value is string {
return typeof value === 'string'
}
这样类型不是any
,而是我们为每种类型提供 1 个类型保护函数,即a -> Boolean
每个a
.
打字稿抱怨说:
类型谓词的类型必须可分配给其参数的类型。类型“字符串”不可分配给类型“T”。
这对我来说没有意义......为什么类型谓词的类型很重要?
解决方案
用户定义的类型保护执行运行时检查以确定特定类型的值是否满足类型谓词。
如果值的类型和类型谓词中的类型之间没有关系,那么守卫将毫无意义。例如,TypeScript 不允许像这样的用户定义保护:
function isString(value: Date): value is string {
return typeof value === "string";
}
并将影响此错误:
[ts] A type predicate's type must be assignable to its parameter's type.
Type 'string' is not assignable to type 'Date'.
一个Date
值永远不会是 a string
,所以守卫是没有意义的:它的运行时检查是不必要的,应该总是 return false
。
当您指定一个通用的、用户定义的类型保护时,T
它可以是任何东西,因此 - 与Date
- 对于某些类型,类型保护将毫无意义。
如果你真的不想使用any
,你可以使用一个空的接口 - {}
- 代替:
function isString(value: {}): value is string {
return typeof value === "string";
}
如果您还想允许将值null
和undefined
值传递给守卫,您可以使用:
function isString(value: {} | null | undefined): value is string {
return typeof value === "string";
}
关于错误消息,谓词类型必须可分配给值类型,因为类型保护用于检查具有较少特定类型的值是否实际上是具有更特定类型的值。例如,考虑这个守卫:
function isApe(value: Animal): value is Ape {
return /* ... */
}
Ape
可分配给Animal
,但反之则不然。
推荐阅读
- javascript - 提交后未发送来自 Stripe 的 TokenKey
- r - R光栅`projectExtent`“不能做这个转换”
- android - android.app.RemoteServiceException:尝试从服务发送通知时 startForeground 的错误通知
- xslt - 计算 xslt 数组中的值
- ssh - 运行包含带有屏幕的 STDIN 重定向的命令
- javascript - 无法控制台记录在另一个项目中有效的 API 响应
- oracle11g - PL/SQL: ORA-00934: 这里不允许使用组函数
- node.js - (节点:26)UnhandledPromiseRejectionWarning:RangeError [EMBED_FIELD_VALUE]:MessageEmbed 字段值可能不为空
- webrtc - 低延迟的 WebRTC 设置
- javascript - 如何在 JavaScript 中使用访问 ID 和密钥获取 CoinEx API?