Skip to content

Instantly share code, notes, and snippets.

@itacirgabral
Created March 31, 2020 13:19
Show Gist options
  • Save itacirgabral/d56d56ad9b42826754ec6265bdceae0a to your computer and use it in GitHub Desktop.
Save itacirgabral/d56d56ad9b42826754ec6265bdceae0a to your computer and use it in GitHub Desktop.
typescript pattern matching
type Dois = { tipo: 'Dois' }
type Cinco = { tipo: 'Cinco' }
type Dez = { tipo: 'Dez' }
type Vinte = { tipo: 'Vinte' }
type Cinquenta = { tipo: 'Cinquenta' }
type Cem = { tipo: 'Cem' }
export type Cedulas = Dois | Cinco | Dez | Vinte | Cinquenta | Cem
type CedulasTipo = Cedulas['tipo']
type CedulasMap<U> = {
[K in CedulasTipo]: U extends { tipo: K } ? U : never
}
type CedulasTipoMap = CedulasMap<Cedulas>
type CedulasPattern<T> = {
[K in keyof CedulasTipoMap]: () => T
}
export const deDois = (): Dois => ({ tipo: 'Dois' })
export const deCinco = (): Cinco => ({ tipo: 'Cinco' })
export const deDez = (): Dez => ({ tipo: 'Dez' })
export const deVinte = (): Vinte => ({ tipo: 'Vinte' })
export const deCinquenta = (): Cinquenta => ({ tipo: 'Cinquenta' })
export const deCem = (): Cem => ({ tipo: 'Cem' })
export default function cedulasMatcher<T> (pattern: CedulasPattern<T>): (cedula: Cedulas) => T {
return cedula => pattern[cedula.tipo]()
}
// https://medium.com/@fillopeter/pattern-matching-with-typescript-done-right-94049ddd671c
import cedulasMatcher, {
deDois,
deCinco,
deDez,
deVinte,
deCinquenta,
deCem
} from './cedulasMatcher'
const caixaFimDoDia = []
caixaFimDoDia.push(deDois())
caixaFimDoDia.push(deCinco())
caixaFimDoDia.push(deDez())
caixaFimDoDia.push(deVinte())
caixaFimDoDia.push(deCinquenta())
caixaFimDoDia.push(deCem())
const pegaValor = cedulasMatcher<number>({
Dois: () => 2,
Cinco: () => 5,
Dez: () => 10,
Vinte: () => 20,
Cinquenta: () => 50,
Cem: () => 100
})
const valorFimDoDia = caixaFimDoDia.reduce((acc, el) => acc + pegaValor(el), 0)
console.log(`O valor no final do dia é de ${valorFimDoDia} Reais`)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment