typescript类型不能赋值问题

最近在学习typescript,遇到了一个问题,两个变量的类型明明相同,却在某些时候不能赋值

代码如下:

enum Enum {
    A = 'a',
    B = 'b',
    C = 'c'
}
interface DataTypes {
    [Enum.B]?: {
        key1: number
        key2: boolean
    }
    [Enum.C]?: {
        key1: number
        key2: boolean
        prefix: string
        suffix: string
    }
}
const someData: DataTypes = {
    [Enum.B]: {
        key1: 2,
        key2: true
    },
    [Enum.C]: {
        key1: 2,
        key2: true,
        prefix: '',
        suffix: ''
    }
}

const onChange = (e) => {
    const { data } = e.target.config
    const type = e.target.value as Enum

    if (type !== Enum.A) {
        (data as DataTypes)[type] = someData[type]
    }
    (data as DataTypes)[type] = someData[type]
}

这段代码最奇怪的是这里,如下图:
image.png

在if块里面赋值是报错的,在外面就能正常赋值,所以我很疑惑,我希望大佬们解答:

  1. 为什么if里面会报错而外面不会
  2. 为什么Emum收窄之后赋值语句左右两边一边是交叉类型的值 另一边是联合类型的值
  3. 如果我把DataTypes里面补上一个Enum.A的值,someData也加上,这个时候不管是if里面还是外面则都会报错,这里面的原因我也想知道

最近接触ts感觉很难受,还望各位大佬们帮帮我,谢谢了

阅读 5.1k
2 个回答

typescript@3.9.4

1)原样照搬代码测试,if里面和外面都会报错,我觉得这样才是正常的,不确定为什么在你的设备会出现不一样的情况,外面的报错是因为缺少Enum.A

2)假设称Enum.B对应的{key1: number; key2: boolean}为IB的话,Enum.C对应IC的话。

someData[type]是交叉类型: 因为在同一时间type只能是Enum.B或Enum.C所以,someData[type]也只能是对应的类型,所以是交叉类型。
data[type]和合并类型,为了满足data[type] = someData[type]一直成立,data[type]需要确保能够接纳等式右边的所有值,所以是合并类型。

// 你以为的: 两边type是一样的
data[Enum.B] = someData[Enum.B]

// 编译器以为地: 两边的type可能不一样,因为ts并不会去推导代码逻辑
data[Enum.B] = someData[Enum.C]

3)就是因为2中的问题

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题