Skip to content

Instantly share code, notes, and snippets.

@mgambill
Last active April 18, 2020 04:49
Show Gist options
  • Save mgambill/4db3925f830c5b6265c6260792a00c10 to your computer and use it in GitHub Desktop.
Save mgambill/4db3925f830c5b6265c6260792a00c10 to your computer and use it in GitHub Desktop.
ValueType example in typescript
const typeKey = Symbol('type');
enum ValueTypeDef {
YEAR = "YEAR",
NAME = "NAME",
TITLE = "TITLE"
}
type ValueType<K extends ValueTypeDef, T> = {
[typeKey]: K;
value: T;
}
interface ValueObject<K extends ValueTypeDef, T> extends Readonly<ValueType<K, T>> { }
interface Name extends ValueObject<ValueTypeDef.NAME, string> { }
interface Title extends ValueObject<ValueTypeDef.TITLE, string> { }
interface Year extends ValueObject<ValueTypeDef.YEAR, number> { }
const ValueType = <K extends ValueTypeDef, T>(type: K, value: T): ValueObject<K, T> => ({ [typeKey]: type, value: value })
function yearOf(value: number): Year {
if (value < 1600) throw new Error("Year must be greater than 1900")
return ValueType(ValueTypeDef.YEAR, value);
}
const nameOf = (value: string): Name => ValueType(ValueTypeDef.NAME, value);
const titleOf = (value: string): Title => ValueType(ValueTypeDef.TITLE, value);
/// implementation examples
const value = "My Book Title";
const age1: Title = { type: ValueTypeDef.TITLE, value }; // not allowed because variable is typed
const title2 = { type: ValueTypeDef.TITLE, value }; // while this is allowed you can't use it with anything that is typed see MakeBook
let age = yearOf(1895)
//age = 2015 ... nope not a valid year even with out explicit typing of age ... TS knows its a Year
//let age3:Year = 2015 ... nope must use yearOf
//age.value = 1906 ... nope value is readonly
const author = nameOf("Rudyard Kipling");
const title:Title = titleOf("Food")
function MakeBook(author:Name, title: Title) {
console.log( { author: author.value, title: title.value } )
return { author: author.value, title: title.value }
}
MakeBook(author, title2) // this raises an error in TS but works in JS
MakeBook(author, title) // this is valid
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment