Last active
September 18, 2021 13:14
-
-
Save karol-majewski/39ebb79602a38c3b0e5d79a0fcc80205 to your computer and use it in GitHub Desktop.
Snippets used in my talk “Who Guards the Type Guards?” (https://www.youtube.com/watch?v=StyKp5dgN_Y)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* A.K.A. type guard | |
*/ | |
type Refinement<T, U extends T> = (candidate: T) => candidate is U; | |
function isString(candidate: unknown): candidate is string { | |
return typeof candidate === 'string'; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
interface Apple { species: 'Malus domestica' } | |
interface Cucumber { species: 'C. sativus' } | |
type Fruit = Apple | Cucumber; | |
/** | |
* Mixed items. | |
*/ | |
declare const basket: Fruit[]; | |
/** | |
* Apples only. | |
*/ | |
let apples: Apple[]; | |
apples = basket.filter((fruit): boolean => fruit.species === 'Malus domestica'); | |
apples = basket.filter((fruit): fruit is Apple => fruit.species === 'Malus domestica'); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export function isString(candidate: unknown): candidate is string { | |
return typeof candidate === 'number'; // 🤷♂️ | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { some, none, getRefinement } from 'fp-ts/lib/Option' | |
const isString = getRefinement<unknown, string>( | |
(candidate) => typeof candidate === 'string' | |
? some(candidate) | |
: none | |
) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Some<T> { | |
constructor(readonly value: T) {} | |
} | |
class None {} | |
type Option<T> = Some<T> | None; | |
function getRefinement<T, U extends T>(getOption: (candidate: T) => Option<U>): Refinement<T, U> { | |
return (candidate: T): candidate is U => | |
getOption(candidate) instanceof Some; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Refinement, { either } from 'refinements'; | |
abstract class Fruit { | |
readonly species: string; | |
} | |
class Orange extends Fruit { | |
readonly species: 'orange'; | |
} | |
class Mango extends Fruit { | |
readonly species: 'mango'; | |
} | |
const isOrange: Refinement<Fruit, Orange> = Refinement.create( | |
fruit => | |
fruit instanceof Orange | |
? Refinement.hit(fruit) | |
: Refinement.miss | |
); | |
const isMango: Refinement<Fruit, Mango> = Refinement.create( | |
fruit => | |
fruit instanceof Mango | |
? Refinement.hit(fruit) | |
: Refinement.miss | |
); | |
const isJuicy = either(isOrange, isMango) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import Refinement, { not } from 'refinements'; | |
type Stable = 'inherit' | 'initial' | 'revert' | 'unset'; | |
type Prefixed = '-moz-initial'; | |
type CSSProperty = Stable | Prefixed; | |
const isPrefixed = Refinement.create( | |
(property: CSSProperty) => | |
property === '-moz-initial' | |
? Refinement.hit(property) | |
: Refinement.miss | |
); | |
const isStandard = not(isPrefixed); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment