Skip to content

Instantly share code, notes, and snippets.

View balanza's full-sized avatar

Emanuele De Cupis balanza

View GitHub Profile
type Foo = {
value: string,
__phantom: never
}
const f = () => { throw '' }
const x: Foo = { value: 'foo', __phantom: f() }
@balanza
balanza / mobile.ts
Last active January 31, 2019 15:33
type ConfirmedMobile = string & { __phantom_1548946378096: never }
const createConfirmedMobile = (num: String) => createOf<ConfirmedMobile, String>(num)
type CertifiedMobile = string & { __phantom_1548946391842: never }
const createCertifiedMobile = (num: String) => createOf<CertifiedMobile, String>(num)
const confirmed = createConfirmedMobile('2984829202')
// ^^^ ConfirmedMobile
const certified = createCertifiedMobile('2984829202')
// ^^^ CertifiedMobile
@balanza
balanza / of.ts
Last active January 31, 2019 14:48
// it's just a cast ;)
const createOf = <T extends Base, Base>(original: Base) => <T>original
@balanza
balanza / mobile.ts
Last active February 1, 2019 08:20
type ConfirmedMobile = string & { __random_transparent_property: never }
type UnconfirmedMobile = string & { __another_random_transparent_property: never }
type CertifiedMobile = string & { __again_random_transparent_property: never }
type Mobile = // ConfirmedMobile | UnconfirmedMobile | CertifiedMobile :)
ConfirmedMobile
| UnconfirmedMobile
| CertifiedMobile
const printString = (p: string) => console.log(`print String ${p}`)
const printConfirmedMobile = (p: ConfirmedMobile) => console.log(`print ConfirmedMobile ${p}`)
type ConfirmedMobile = string
type UnconfirmedMobile = string
type CertifiedMobile = string
type Mobile = // just string :(
ConfirmedMobile
| UnconfirmedMobile
| CertifiedMobile
const exhaustionCheck = (e: never) => console.log('this will never be executed')
const printMobileSafe = (mobile: Mobile) => {
if(mobile.status === 'confirmed') {
console.log('Your mobile is confirmed!')
} else if(mobile.status === 'unconfirmed') {
console.warn('Your mobile is not confirmed!')
} else {
exhaustionCheck(mobile) // <-- you'll get a compilation error here!
}
const certified: CertifiedMobile = { status: 'certified', value: '543234531' }
printMobile(certified) // warn: Your mobile is not confirmed!
printMobileAlternative(certified) // unhandled exception: illegal state! mobile.status=certified
// add this line
type CertifiedMobile = Valued<string> & { status: 'certified' }
// add CertifiedMobile to the unon type
type Mobile = ConfirmedMobile | UnconfirmedMobile | CertifiedMobile
// optimistic implementation: assume mobile.status will only have those two values
const printMobile = (mobile: Mobile) => {
if(mobile.status === 'confirmed') {
console.log('Your mobile is confirmed!')
} else {
console.warn('Your mobile is not confirmed!')
}
}
// defensive implementation: assume mobile.status can be whatever
type Valued<T> = { value: T }
type ConfirmedMobile = Valued<string> & { status: 'confirmed' }
type UnconfirmedMobile = Valued<string> & { status: 'unconfirmed' }
type Mobile = ConfirmedMobile | UnconfirmedMobile
type User {
/* name, surname, etc */
mobile: Mobile
}
// an user with confirmed mobile