【问题标题】:Typescript not inferring types in switch statement when generics and conditionals are used in the type definition当类型定义中使用泛型和条件时,Typescript 不会在 switch 语句中推断类型
【发布时间】:2019-10-30 15:14:30
【问题描述】:

我有一个函数的类型定义。我将第二个参数的类型定义为以第一个参数的类型为条件,如下所示:

const FOO = "FOO";
const BAR = "BAR";

let fooPayload = {
    zip: "zap"
}
let barPayload = {
    cat: "dog"
}

type ActionTypes = typeof FOO | typeof BAR;
interface MyFunction<T extends ActionTypes = ActionTypes> {
  (
    action: {
      type: T;
      payload: T extends typeof FOO
        ? typeof fooPayload
        : typeof barPayload;
    }
  ): boolean;
}

MyFunction 接口引用的函数内部有一个 switch 语句,该语句基于 action.type 进行切换,并根据情况对action.payload 执行某些操作。这是一个例子:

const myFunction:MyFunction = (action) => {
    switch (action.type) {
        case FOO:
            action.payload.zip = "new zap"
            return true
        case BAR: 
            action.payload.cat = "new dog"
            return false
        default:
            return false
    }
}

我遇到的问题是 Typescript 没有正确地从 switch 语句中推断出 action.payload 应该是什么。例如,如果action.type 等于“FOO”,那么它应该推断出action.payload 必须是typeof fooPayload。相反,它推断它是typeof fooPayload | typeof barPayload

这没有任何意义,因为action.payload 的类型定义基于action.type 的值,并且因为action.payload.zip 是在switch 语句中调用的只有在@987654335 时才会发生@ 等于“FOO”,它应该推断出action.payload 唯一可能的类型是typeof fooPayload

Here's a code example

我在这里做错了什么?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    我不确定这会导致问题的确切位置,但总的来说,问题是您正在尝试重新发明 typescript 已经做得很好的东西,缩小类型联合。

    条件是一个非常有趣的功能,但有时会表现得有些出人意料,因为它们是可分配的,因为它们会超出定义的范围。

    我会以不同的方式实现:

    interface Action<T, P> {
        type: T,
        payload: P
    }
    
    type Actions 
        = Action<typeof FOO, typeof FooPayload> 
        | Action<typeof BAR, typeof BarPayload> 
        ;
    
    interface MyFunction {
      (action: Actions): boolean;
    }
    

    不需要条件,打字稿将在切换中按预期缩小联合。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-07-28
      • 2019-09-17
      • 1970-01-01
      • 2020-09-22
      • 2022-08-17
      • 2018-01-18
      • 2018-10-20
      • 1970-01-01
      相关资源
      最近更新 更多