typescript - 如何断言泛型是 NonNullable
问题描述
我有一些方法用于NonNullable<T>
允许某些部分假定在调用之前已执行空值检查。我还有一个函数可以在调用上述方法之前执行该检查。
我的问题是这个函数接受一个T
我需要缩小到的泛型NonNullable<T>
。在编写检查null
和undefined
值的保护代码时,这种类型不会通过推理自动缩小为不可为空的类型。
export interface UrlParam<T> {
defaultValue: T,
encode: (value: NonNullable<T>) => string
decode: (value: string) => NonNullable<T>
}
interface LatLng {
lat: number
lng: number
}
const COORDINATE_DELIMITER = ','
const locationParam: UrlParam<LatLng | null> = {
defaultValue: null,
encode: ({ lat, lng }) => [lat, lng].join(COORDINATE_DELIMITER),
decode: value => {
const [lat, lng] = value.split(COORDINATE_DELIMITER)
return {
lat: Number(lat),
lng: Number(lng),
}
}
}
function encodeParam<T>(urlParam: UrlParam<T>, value: T) {
return value !== undefined && value !== null ? urlParam.encode(value) : null
}
该encodeParam
函数产生以下编译错误:
“T”类型的参数不能分配给“NonNullable”类型的参数
我可以通过强制 TypeScript 编译器将T
其视为NonNullable<T>
:
urlParam.encode(value as NonNullable<T>)
但是,我正在寻找一种解决方案,其中编译器实际上可以根据条件本身推断出这种类型。这可能吗?我可能以错误的方式接近这个吗?
解决方案
虽然有朝一日可能通过控制流分析而不是类型断言或使用非空断言运算符value as NonNullable<T>
的 terser来做这种事情,但现在编译器不会自己做这件事。value!
相反,如果您想要编译器可以遵循的东西,我的建议是从“我需要删除的可能或类型”T
更改为“null
我可能需要删除的非和非类型”添加and 。您可以使用空类型来表示“除and之外的任何内容”(是的,即使是像这样的原语也可以分配给),并进行约束以使 no或类型可以潜入您的类型。undefined
null
undefined
null
undefined
null
undefined
{}
null
undefined
string
{}
T extends {}
undefined
null
T
重构将如下所示:
export interface UrlParam<T extends {}> {
defaultValue: T | null | undefined,
encode: (value: T) => string
decode: (value: string) => T
}
然后UrlParam<LatLng | null>
你可以写而不是UrlParam<LatLng>
,最后以下encodeParam
将按预期工作,因为编译器可以使用控制流分析来过滤一个类型的值,T | null | undefined
只需T
检查它:
function encodeParam<T extends {}>(urlParam: UrlParam<T>, value: T) {
return value !== undefined && value !== null ? urlParam.encode(value) : null // okay
}
推荐阅读
- javascript - 如何将键/值对数组更新为猫鼬?
- java - android.view.InflateException:二进制 XML
- python - Python websockets错误处理:越来越多的线程
- python - 方法参数还是实例属性?
- excel - vba 宏从一张表中复制数据并将其保存为新工作簿
- c++ - C++ 类图和 {query}
- c++ - 在 C++ 中访问蓝图类组件的正确方法是什么
- javascript - 为什么复选框没有选中反应?
- c# - 如何在 C# 中使用 OpenXML 将 RTF/HTML 放入 Excel 单元格
- ocaml - 结合参数多态性和多态变体(反引号类型)