Typescript 通过字段推断文本对象的类型
我在接口中有一些属性。将这些属性划分为两个接口,然后声明两者的联合类型似乎是可行的 请查看下面的简化情况,其中函数需要百分比或固定值。在每个接口中添加一个属性,说明其是否为一个类型(isPercent),并将该类型约束为特定值,这样函数的逻辑就可以检测所传递参数的类型,而typescript——令人惊讶的是——似乎也可以推断出该类型,但仅限于此 很难对其进行描述,但我希望代码能让您了解:Typescript 通过字段推断文本对象的类型,typescript,type-inference,Typescript,Type Inference,我在接口中有一些属性。将这些属性划分为两个接口,然后声明两者的联合类型似乎是可行的 请查看下面的简化情况,其中函数需要百分比或固定值。在每个接口中添加一个属性,说明其是否为一个类型(isPercent),并将该类型约束为特定值,这样函数的逻辑就可以检测所传递参数的类型,而typescript——令人惊讶的是——似乎也可以推断出该类型,但仅限于此 很难对其进行描述,但我希望代码能让您了解: interface IPcentFee { isPercent: true, percentFee: num
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分析的,带有接口的联合类型在Typescript中很有趣,通常需要具有通用属性,以便您直接引用它们。因此,您的界面可以是:
interface IPcentFee { isPercent: true, fee: number }
interface IFixedFee { isPercent: false, fee: number }
并通过以下方式访问:
discount = value * parm.fee
fee
可以是公共的,因为您正在检查公共属性isPercent
或者,您可以将else子句强制转换为以下内容,这样不会抛出错误
discount = (<IFixedFee>parm).fixedFee
折扣=(每平方米)。固定费用
在Typescript中,带有接口的联合类型很有趣,通常需要具有公共属性,以便直接引用它们。因此,您的界面可以是:
interface IPcentFee { isPercent: true, fee: number }
interface IFixedFee { isPercent: false, fee: number }
并通过以下方式访问:
discount = value * parm.fee
fee
可以是公共的,因为您正在检查公共属性isPercent
或者,您可以将else子句强制转换为以下内容,这样不会抛出错误
discount = (<IFixedFee>parm).fixedFee
折扣=(每平方米)。固定费用
这确实很有趣 看看这个:
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
。如果启用stricnullchecks
标记,则代码正常工作
如果未启用
stricnullchecks
,则默认情况下每个类型都可以为空,因此您仍然需要将isPercent
检查为null
/未定义的
。启用该标志使每个类型在默认情况下都不可为空,因此实际上只有两种可能性(对于类型检查而言)是true
或false
,这确实非常有趣
看看这个:
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
。如果启用stricnullchecks
标记,则代码正常工作
如果未启用
stricnullchecks
,则默认情况下每个类型都可以为空,因此您仍然需要将isPercent
检查为null
/未定义的
。启用该标志使每个类型在默认情况下都不可为空,因此实际上只有两种可能性(对于类型检查)是true
或false
这是什么版本的typescript?我在我的机器上运行了你的代码,它收到了FixedFee奇怪的是,(parm.isPercent==true)
为我修复了类型推断错误(TS 2.6.1)。我正在使用TS 2.9.1,我将更新原始Post。这是什么版本的typescript?我在我的机器上运行了你的代码,它获得了FixedFee奇怪的是,(parm.isPercent==true)
为我修复了类型推断错误(TS 2.6.1)。我正在使用TS 2.9.1,我将更新原始帖子