我在界面中有一些其他属性。将这些属性划分为两个接口,然后声明两者的联合类型似乎是可行的方法。
请查看以下简化情况,其中函数需要百分比或固定值。向每个接口添加一个prop,表明它的一个类型(isPercent)并将类型约束为特定值,允许函数的逻辑检测传递的参数类型和typescript -amazingly-似乎也推断类型但仅。
很难描述它,但我希望代码会给你一个想法:
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似乎从条件if (parm.isPercent)
推断类型IPcentFee,但为什么else子句不推断替代类型?
通过ts 版本2.9.1
分析样品答案 0 :(得分:3)
确实非常有趣。
看看这个:
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)
更改为if (parm.isPercent === true)
即可完成作业,并且每个分支的类型都会按预期缩小。我不得不承认我不完全确定为什么其他方法不起作用。我想这是因为truthy
/ true
差异......但是,如图所示,您可以与文字值进行比较,因此您无需手动断言。
<强>更新强>
事实上,它看起来是一个差异,但不是truthy
/ true
而是falsy
/ false
。如果您启用了strictNullChecks
标记,那么您的代码就可以正常运行。
默认情况下,如果strictNullChecks
未启用,则每种类型都可以,因此您仍然需要检查isPercent
至null
/ undefined
。默认情况下启用该标志使每个类型不可为空,因此实际上只有两种可能性(对于类型检查)是true
或false
。
答案 1 :(得分:0)
带有接口的联合类型在Typescript中很有趣,通常需要具有公共属性才能直接引用它们。所以你的界面可能是:
interface IPcentFee { isPercent: true, fee: number }
interface IFixedFee { isPercent: false, fee: number }
并访问:
discount = value * parm.fee
fee
可能很常见,因为您正在检查公共财产isPercent
。
或者,您可以在else子句中强制转换为以下内容,这不会引发任何错误。
discount = (<IFixedFee>parm).fixedFee