Advance Flow type #1: Exhaustive checking with empty type

Exhaustive Checking

const f = (x: 'A' | 'B') => {
if (x === 'A') {
return 0
}
}
const f = (x: 'A' | 'B'): number => {
if (x === 'A') {
return 0
} else {
return 1
}
}
// type.jstype X = 'A' | 'B'
// function.jsconst f = (x: X): number => {
if (x === 'A') {
return 0
} else {
return 1
}
}
type X = 'A' | 'B' | 'C'

Empty Type

const f = (x: X): number => {
if (x === 'A') {
return 0
} else if (x === 'B') {
return 1
} else {
(x: empty)
throw new Error(`${x} is not an element of type 'X'`)
}
}
const f = (x: X): number => {
if (x === 'A') {
return 0
} else if (x === 'B') {
return 1
} else if (x === 'C') {
return 2
} else {
(x: empty)
throw new Error(`${x} is not an element of type X`)
}
}
const f = (x: X): number => {
if (x === 'A') {
return 0
} else if (x === 'B') {
return 1
} else if (x === 'C') {
return 2
} else {
return (x: empty)
}
}
number | empty

More example

type MaxRule = {
type: 'MAX',
maxValue: number,
}
type MinRule = {
type: 'MIN',
minValue: number,
}
type ForAllRule = {
type: 'FOR_ALL',
rules: Rule[]
}
type ForSomeRule = {
type: 'FOR_SOME',
rules: Rule[]
}
type Rule = MinRule | MaxRule | ForAllRule | ForSomeRule
const validate = (value: number, rule: Rule): boolean => {
switch (rule.type) {
case 'MAX':
return value <= rule.maxValue
case 'MIN':
return value >= rule.minValue
case 'FOR_ALL':
return rule.rules
.reduce((acc, nextRule) => acc && validate(value, nextRule), true)
case 'FOR_SOME':
return rule.rules
.reduce((acc, nextRule) => acc || validate(value, nextRule), false)
default:
(rule.type: empty)
throw Error(`rule ${rule.type} is not being handled properly`)
}
}

Conclusion

CTO @ Coindee; EX-ThoughtWorker; FP, Math, Stats, Blockchain & Human Enthusiast