我具有以下类型和转换功能:
type LeftRightField = null |
{ left: null, right: number } |
{ left: number, right: null } |
{ left: number, right: number }
type LeftRightArray = [null, number] |
[number, null] |
[number, number] |
null
const fmtField = function (field: LeftRightField): LeftRightArray {
const rightField = field?.right ?? null
const leftField = field?.left ?? null
return (leftField == null && rightField == null) ? null : [leftField, rightField]
}
但是这失败了
输入'number | null”不能分配给类型“ null”。
不能将“数字”类型分配给“空”类型
进行转换的正确方法是什么?
答案 0 :(得分:5)
这似乎是TypeScript的实例,无法跟踪我一直在调用的correlated types。在您的情况下,leftField
和rightField
都是联合类型number | null
。不幸的是,当您进行类型防护时,编译器不会将它们视为在一起。它将它们视为不相关的,因此即使[leftField, rightField]
子类型是不可能的,[number | null, number | null]
也被视为类型[null, null]
。
在这里要做的唯一“正确”的事情,不仅仅是放弃和asserting这样的事情是安全的:
return (leftField === null && rightField === null) ? null :
[leftField, rightField] as LeftRightArray;
将代码重构为可能冗余的独立代码路径,编译器可以使用control flow analysis进行验证:
return (leftField === null) ? (
rightField === null ? null : [leftField, rightField]
) : [leftField, rightField];
如果您仅使用两个字段,则可以。如果您使用的资源不止这些,那么冗余可能太多了,您只需断言然后继续。