Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typescript/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 通过字段推断文本对象的类型_Typescript_Type Inference - Fatal编程技术网

Typescript 通过字段推断文本对象的类型

Typescript 通过字段推断文本对象的类型,typescript,type-inference,Typescript,Type Inference,我在接口中有一些属性。将这些属性划分为两个接口,然后声明两者的联合类型似乎是可行的 请查看下面的简化情况,其中函数需要百分比或固定值。在每个接口中添加一个属性,说明其是否为一个类型(isPercent),并将该类型约束为特定值,这样函数的逻辑就可以检测所传递参数的类型,而typescript——令人惊讶的是——似乎也可以推断出该类型,但仅限于此 很难对其进行描述,但我希望代码能让您了解: interface IPcentFee { isPercent: true, percentFee: num

我在接口中有一些属性。将这些属性划分为两个接口,然后声明两者的联合类型似乎是可行的

请查看下面的简化情况,其中函数需要百分比或固定值。在每个接口中添加一个属性,说明其是否为一个类型(isPercent),并将该类型约束为特定值,这样函数的逻辑就可以检测所传递参数的类型,而typescript——令人惊讶的是——似乎也可以推断出该类型,但仅限于此

很难对其进行描述,但我希望代码能让您了解:

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,我将更新原始帖子