代码之家  ›  专栏  ›  技术社区  ›  Vladyslav Zavalykhatko

在typescript中切换特定类型

  •  3
  • Vladyslav Zavalykhatko  · 技术社区  · 6 年前

    我有一个接口 Action 以下内容:

    interface Action {}
    

    以及这个的实现 行动 SpecificAction 以下内容:

    class SpecificAction implements Action {
       payload?: Any
    }
    

    在TS中,是否可以构造一个开关运算符,如下所示:

    let action: Action
    switch (action) {
       case SpecificAction: //it works
           console.log(action.payload) // it doesn't 
    }
    

    在这种情况下,是否有可能知道,该行动已经

    2 回复  |  直到 5 年前
        1
  •  1
  •   Dan Dohotaru    5 年前

    interface Action {}
    
    class SpecificAction implements Action {
      kind: "specific";
      payload?: any;
    }
    
    class ToggleAction implements Action {
      kind: "toggle";
      toggle: boolean;
    }
    
    let action: SpecificAction | ToggleAction;
    switch (action.kind) {
      case "specific":
        console.log(action.payload) // it works 
        break;
      case "toggle":
        console.log(action.toggle) // it works 
        break;        
    }
    
    interface Action {}
    
    class SpecificAction implements Action {
      payload?: any;
    }
    
    class ToggleAction implements Action {
      toggle: boolean;
    }
    
    let isSpecific = (p: any): p is SpecificAction => !!p.payload
    let isToggle = (p: any): p is ToggleAction => !!p.toggle
    
    let action: Action;
    if (isSpecific(action)) {
      console.log(action.payload) // it works 
    } else if (isToggle(action)) {
      console.log(action.toggle) // it works 
    }
    
    interface Action { }
    
    class SpecificAction implements Action {
      payload?: any;
    }
    
    class ToggleAction implements Action {
      toggle: boolean;
    }
    
    switch (action.constructor) {
      case SpecificAction:
        console.log((<SpecificAction>action).payload) // it kinda works 
        break;
      case ToggleAction:
        console.log((<ToggleAction>action).toggle) // it kinda works 
        break;
      }
    
        2
  •  3
  •   pushkin Void Star    6 年前

    if

    let action: Action = ...;
    if (isSpecificAction(action)) {
        console.log(action.payload);
    }
    
    function isSpecificAction(action: any): action is SpecificAction {
        return action.payload;
    }
    

    switch switch 以下内容:

    switch语句首先计算其表达式。然后查找第一个case子句,其表达式的计算结果与输入表达式的结果相同(使用严格比较,==)

    所以在你的例子中:

    interface Action {}
    class SpecificAction implements Action {
       payload?: any
    }
    
    let action: Action
    switch (action) {
       case SpecificAction: //it works
           console.log(action.payload) // it doesn't 
    }
    

    action 将被评估并与 班级 SpecificAction .大概, 行动 是一个 实例 属于 具体行动 (或实现 Action 接口)。

    用一个 转换 ,您可以这样做:

    let a: Action = new SpecificAction();
    let b: Action = a;
    
    switch (a) {
        case b:
            console.log("Worked");
    }
    

    表达式 a 计算并与表达式进行比较 b (和 a === b ,所以我们点击 console.log 但这显然不是你想要的。

    如果要检查实例是否属于特定类型(re:class),则应使用类型保护。A switch/case 是错误的构造。


    或者,为什么不使用 instanceof 是吗?

    interface Action { };
    class SpecificAction implements Action {}
    class NotSpecificAction implements Action {}
    
    let action: Action = new SpecificAction();
    console.log(action instanceof SpecificAction); // true
    console.log(action instanceof NotSpecificAction); // false