typescript - 通过字段推断文字对象联合的类型
问题描述
我在界面中有一些单独的属性。将这些属性划分为两个接口,然后声明两者的联合类型似乎是可行的方法。
请看下面的简化情况,其中函数需要百分比或固定值。向每个接口添加一个道具,说明其是否为一种类型(isPercent)并将类型限制为特定值,允许函数的逻辑检测传递的参数的类型,并且打字稿 - 令人惊讶地 - 似乎也可以推断类型但仅.
很难描述它,但我希望代码能给你这个想法:
interface IPcentFee { isPercent: true, percentFee: number }
interface IFixedFee { isPercent: false, fixedFee: number }
let parm = { isPercent: true, percentFee: 0.15 }
function calculate(parm:IPcentFee | IFixedFee){
let value = 100, discount
if (parm.isPercent)
discount = value * parm.percentFee // Here ts infers type of parm being IPecentFee
else
discount = parm.fixedFee // ts error: Property 'fixedFee' does not exist on type 'IPcentFee | IFixedFee'
....
}
TS 似乎从条件推断类型 IPcentFeeif (parm.isPercent)
但为什么 else 子句不推断替代类型?
样本通过 ts 2.9.1 版本进行分析
解决方案
这确实很有趣。
看这个:
interface IPcentFee { isPercent: true, percentFee: number }
interface IFixedFee { isPercent: false, fixedFee: number }
let parm = { isPercent: true, percentFee: 0.15 }
function calculate(parm:IPcentFee | IFixedFee){
let value = 100, discount
if (parm.isPercent === true) // Comparing to literal `true`
discount = value * parm.percentFee
else
discount = parm.fixedFee // it works!
}
只需更改if (parm.isPercent)
to 即可if (parm.isPercent === true)
完成工作,并且每个分支中的类型都按预期缩小。我不得不承认我不完全确定为什么另一种方式不起作用。我想这是由于truthy
/true
差异造成的......但是,如图所示,您可以与文字值进行比较,因此您无需手动断言。
更新:
事实上,它看起来是由于差异,但不是truthy
/true
而是falsy
/ false
。如果您启用该strictNullChecks
标志,您的代码就可以正常工作。
如果strictNullChecks
未启用,默认情况下每种类型都可以为空,因此您仍然需要isPercent
检查null
/ undefined
。启用该标志使每个类型默认情况下都不可为空,因此实际上只有两种可能性(至于类型检查)是true
or false
。
推荐阅读
- mysql - 如何限制左连接中的记录
- python - 无法在 Python 中将范围插入谷歌表格
- node.js - Azure 上的 Express App 无法加载静态文件,状态 500
- xml - 为什么在 Odoo 11 中安装模块时出现错误“在字符串格式化期间没有转换所有参数”?
- python - 拟合曲线时的 TypeError
- sql - 在不引用对偶表的情况下,在 Oracle 中从无中选择?
- r - 需要找到一个模式并将其提取出来
- sql - SQL | 无论最后一个整数值如何,如何总是四舍五入,即使它可能是 0
- javascript - 方括号中的对象和某些键如何工作?
- html - Python3 Django Webapp HTML 测试按钮打印调试数据