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)
}
}
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.
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.
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.
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.
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'
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With