Last active
July 1, 2022 17:36
-
-
Save cullylarson/7c1c0dfe1217ba6cfbfa749128811d21 to your computer and use it in GitHub Desktop.
Typescript Branding and Flavoring
This file contains 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
/* eslint-disable @typescript-eslint/no-unused-vars */ | |
/* eslint-disable no-console */ | |
/* ************************************** */ | |
export interface Branding<BrandT> { | |
_type: BrandT; | |
} | |
export type Brand<T, BrandT> = T & Branding<BrandT>; | |
type BrandedPersonIdEasy = Brand<number, 'BrandedPerson'>; | |
type BrandedPersonId = number & { | |
_type: 'BrandedPerson'; | |
}; | |
/* ************************************** */ | |
export type Flavor<T, FlavorT> = T & Flavoring<FlavorT>; | |
export interface Flavoring<FlavorT> { | |
_type?: FlavorT; | |
} | |
type FlavoredPersonIdEasy = Flavor<number, 'FlavoredPerson'>; | |
type FlavoredPersonId = number & { | |
_type?: 'FlavoredPerson'; | |
}; | |
/* ************************************** */ | |
const brandedPersonId0: BrandedPersonId = 12; // error | |
const brandedPersonId: BrandedPersonId = 12 as BrandedPersonId; | |
const flavoredPersonId: FlavoredPersonId = 12; | |
const plainPersonId = 12; | |
/* ************************************** */ | |
function logBrandedPersonId(personId: BrandedPersonId) { | |
console.log(personId); | |
} | |
logBrandedPersonId(brandedPersonId); // ok | |
logBrandedPersonId(flavoredPersonId); // error | |
logBrandedPersonId(plainPersonId); // error | |
/* ************************************** */ | |
function logFlavoredPersonId(personId: FlavoredPersonId) { | |
console.log(personId); | |
} | |
logFlavoredPersonId(brandedPersonId); // error | |
logFlavoredPersonId(flavoredPersonId); // ok | |
logFlavoredPersonId(plainPersonId); // ok | |
/* ************************************** */ | |
type SomethingOne = number; | |
type SomethingTwo = number; | |
const one: SomethingOne = 1; | |
const two: SomethingTwo = 2; | |
function logOne(x: SomethingOne) { | |
console.log(x); | |
} | |
function logTwo(x: SomethingTwo) { | |
console.log(x); | |
} | |
logOne(one); // ok | |
logOne(two); // ok | |
logTwo(one); // ok | |
logTwo(two); // ok |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment