Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Switch for specific type in TypeScript

Tags:

typescript

I have an interface Action:

interface Action {} 

And an implementation of this Action SpecificAction:

class SpecificAction implements Action {    payload?: Any } 

Is it possible in TS to construct a switch operator, like this:

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

Is it possible in that case to know, that action is already of SpecificAction type?

like image 472
Vladyslav Zavalykhatko Avatar asked Jun 09 '18 13:06

Vladyslav Zavalykhatko


People also ask

What is switch in TypeScript?

The switch statement is used to check for multiple values and executes sets of statements for each of those values. A switch statement has one block of code corresponding to each value and can have any number of such blocks.

How do I assign two TypeScript types?

TypeScript allows you to define multiple types. The terminology for this is union types and it allows you to define a variable as a string, or a number, or an array, or an object, etc. We can create union types by using the pipe symbol ( | ) between each type.

What does the IS keyword do in TypeScript?

The is keyword is actually casting the type and can catch type errors later in the code. See this example for more info. @benjaminz I don't see how it could be handled by a boolean. Typescript needs to know that the function into which you pass an object is functioning like a type guard.


1 Answers

for the time being it looks like there are a few options, all of them with some drawbacks

  • discriminated unions docs stackblitz, but you'll need a dedicated property as discriminator
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;         } 
  • User-Defined Type Guards docs stackblitz, but you'll need if statements instead of switch
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  } 
  • constructor property github stackblitz, but you'll need to cast to desired type for the time being
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;   } 
like image 184
Dan Dohotaru Avatar answered Oct 04 '22 11:10

Dan Dohotaru