typescript - 自定义未定义检查的打字稿推断
问题描述
我无法想象这个问题还没有被问过,但我找不到。这可能与不知道要搜索哪些关键字来描述我的问题有关。
无论如何,假设我们有这个打字稿:
const value = undefined
const doSomethingWithValue = (value: number) => console.log(value)
const isDefined = (value?: unknown) => value != null
if (value != null) {
doSomethingWithValue(value) // Works great!
}
if (isDefined(value)) {
doSomethingWithValue(value) // Boo, error!: Argument of type 'undefined' is not assignable to parameter of type 'number'.
}
如您所见,该isDefined
函数检查null
/ undefined
,但 Typescript 似乎无法像在if
语句中使用显式检查时那样弄清楚它。我知道我可以像这样添加类型提示:
if (isDefined(value)) {
doSomethingWithValue(value as unknown as number) // Works, but "eh"
}
这没关系,我想 - 绝对不理想。没有更好的方法吗?
编辑:非空断言运算符
所以,我刚刚了解到我可以像这样使用“非空断言运算符”,但它仍然不是“好”:
if (isDefined(value)) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
doSomethingWithValue(value!) // Works, not ideal still...
}
这可行,但需要禁用 eslint 规则@typescript-eslint/no-non-null-assertion
:https://github.com/typescript-eslint/typescript-eslint/blob/v5.1.0/packages/eslint-plugin/docs/rules/no-non-null-assertion。 md,文档警告:“使用非空断言取消了严格的空检查模式的好处。” 和“如果你不关心严格的空值检查,那么你就不需要这条规则。”
但是,我确实关心严格的空值检查!我不想完全禁用它
解决方案
首先:
if (value != null) {
doSomethingWithValue(value) // Works great!
}
它效果不佳。value
被推断为never
并可never
分配给任何类型。
如果你想使用value
and isDefined
,你应该转换isDefined
成自定义类型保护:
declare const value: undefined | null | number;
const doSomethingWithValue = (value: number) => console.log(value)
const isDefined = <T,>(value: T | null | undefined):
value is NonNullable<T> =>
value != null && value !== undefined
if (isDefined(value)) {
doSomethingWithValue(value) // ok
}
declare const value2: undefined | null | string;
if (isDefined(value2)) {
value2 // string
}
推荐阅读
- vb.net - 输出为 CSV 文件时,半角片假名出现乱码/不可读
- javascript - 关闭模态窗口时停止音频
- css - 仅使用 css 悬停另一个 div 时显示 div
- php - “子查询返回超过 1 行”的解决方案
- swiftui - 修复表达式类型不明确,没有更多上下文 Amplify Model
- javascript - 在 Vue js 中,Json 响应对象的用户名字段显示为 null 而在后端完美运行
- python - 使用 matplotlib 重新映射 y 轴标签的子集
- swift - 在 SwiftUI 中,如何限制 ObservableObject 的哪些 @Published 属性触发视图刷新?
- javascript - 为什么我不能让这个 Svg 重音栏在 javascript 事件侦听器上缩小
- reactjs - 如何将函数传递给不同的组件反应