Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sealed case classes in flow

I'm trying to emulate Scala's sealed case classes in Flow by using disjoint unions:

type ADD_TODO = {
  type:'ADD_TODO',
  text:string,
  id:number
}

type TOGGLE_TODO = {type:'TOGGLE_TODO', id:number }

type TodoActionTy = ADD_TODO | TOGGLE_TODO


const todo = (todo:TodoTy, action:TodoActionTy) => {
  switch (action.type){
      case 'ADD_TODO' :
          return { id:action.id, text:action.text, completed: false};
      case 'TOGGGGLE_TODO': // this should give a type error 
        if (todo.id !== action.id) {return todo;}
          return {...todo, completed:!todo.completed};
  }
}

I should get a type error for case 'TOGGGGLE_TODO': but I don't.

Is there a way to fix that ?

EDIT:

I paste here the code from Gabriele's comment for future-proof-ness:

type TodoTy = {};

type ADD_TODO = { type: 'ADD_TODO', text: string, id: number };

type TOGGLE_TODO = { type: 'TOGGLE_TODO', id: number };

type TodoActionTy = ADD_TODO | TOGGLE_TODO;

export const todo = (todo: TodoTy, action: TodoActionTy) => {
  switch (action.type){
    case 'ADD_TODO': break;
    // Uncomment this line to make the match exaustive and make flow typecheck
    //case 'TOGGLE_TODO': break;
    default: (action: empty)
  }
}
like image 530
jhegedus Avatar asked Oct 31 '16 08:10

jhegedus


People also ask

What are sealed classes?

Sealed classes are used to restrict the users from inheriting the class. A class can be sealed by using the sealed keyword. The keyword tells the compiler that the class is sealed, and therefore, cannot be extended. No class can be derived from a sealed class.

What is sealed class with example?

A sealed class, in C#, is a class that cannot be inherited by any class but can be instantiated. The design intent of a sealed class is to indicate that the class is specialized and there is no need to extend it to provide any additional functionality through inheritance to override its behavior.

What is difference between sealed class and private class?

A Private class can only be accessed by the class it is defined and contain within - it is completely inaccessible to outside classes. A Sealed class can be accessed by any class, but can not be derived from.

What is the difference between sealed and abstract classes?

The abstract keyword enables you to create classes and class members that are incomplete and must be implemented in a derived class. The sealed keyword enables you to prevent the inheritance of a class or certain class members that were previously marked virtual.


1 Answers

The empty type can be used to verify that Flow is convinced of exhaustiveness

export const todo = (todo: TodoTy, action: TodoActionTy) => {
  switch (action.type){
    case 'ADD_TODO' :
      ...
    case 'TOGGGGLE_TODO':
      ...
    default :
      // only true if we handled all cases
      (action: empty)
      // (optional) handle return type
      throw 'unknown action'
  }
}
like image 137
gcanti Avatar answered Sep 28 '22 00:09

gcanti