为什么Typescript抛出错误消息:类型上不存在属性?

为什么Typescript抛出错误消息:类型上不存在属性?,typescript,redux,Typescript,Redux,我创建了两个代码示例。它们之间唯一的区别是我传递给switch操作符的表达式 在第一种情况下,我使用对象属性。而且效果很好 在第二种情况下,我创建了一个类型变量。和Typescript会抛出一条错误消息: 类型“Action”上不存在属性“name” 类型“{type:“reset”;}”上不存在属性“name” 为什么会这样 对象属性action.type和变量type属于同一类型'reset'|'update' 接口状态{ 名称:字符串; 汽车:任何[]; } 类型操作={type:'re

我创建了两个代码示例。它们之间唯一的区别是我传递给switch操作符的表达式

在第一种情况下,我使用对象属性。而且效果很好

在第二种情况下,我创建了一个
类型
变量。和Typescript会抛出一条错误消息:

类型“Action”上不存在属性“name”

类型“{type:“reset”;}”上不存在属性“name”

为什么会这样

对象属性
action.type
和变量
type
属于同一类型
'reset'|'update'

接口状态{
名称:字符串;
汽车:任何[];
}

类型操作={type:'reset'}{type:'update',name:string}; 函数缩减器(状态:状态,操作:操作):状态{ 开关(动作类型){ 案例“更新”: 返回{…状态,名称:action.name}; 案例“重置”: 返回{…状态,车辆:[]}; 违约: 抛出新错误(); }
}
基本上,Typescript不跟踪变量类型
action
type
之间的关系;当
类型
的类型缩小时(例如在
开关
语句的
情况下),它也不会缩小
操作
的类型

关于赋值
const{type}=action,编译器推断出
类型:操作['type']
,它恰好是
'reset'|'update'
。稍后,由于未对
操作
执行类型保护检查,因此
大小写
表达式不会缩小
操作
的类型

要使其按您希望的方式运行,编译器必须引入类型变量
T extensed Action['type']
并推断
type:T
,同时将
Action
缩小到类型
:Action&{type:T}
。然后当
type
的类型缩小时,
T
本身必须缩小,因此效果将传播到
action
的类型,这将涉及
T


在每个变量赋值中引入这样的新类型变量,控制流缩小类型变量的上界,将使类型检查算法变得非常复杂。这也会使推断的类型变得非常复杂,让用户更难理解;所以Typescript不这样做是合理的。一般来说,类型检查器不会证明代码的每个可证明属性,这就是一个例子。

当您引用参数时,它可以从整个对象推断类型,但当您创建一个常量时,您将类型限制为简单的
“reset”|“update”
和操作对象类型信息的其他位丢失。

类型操作={type:'reset'}{type:'update',name:string};您必须在此处为name属性设置一个值,而不是name:string。