Last active
November 13, 2016 15:32
-
-
Save aseemk/2ac1dfbc08bfd18b92da7d9fc8b0a838 to your computer and use it in GitHub Desktop.
An example of how to use TypeScript's impressive type inference with both generics and function overloads to achieve robust static typing with runtime type knowledge too! Playground: http://tinyurl.com/hxue2sw
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
type StaticValueType = string | number | boolean; | |
type StringValueType = 'string' | 'number' | 'boolean'; | |
function parse(val: string): 'string'; | |
function parse(val: number): 'number'; | |
function parse(val: boolean): 'boolean'; | |
function parse<T extends StringValueType>(val: null, valType: T): T; | |
function parse(val: StaticValueType | null, valType?: StringValueType): StringValueType { | |
if (val == null) { | |
if (valType == null) { | |
throw new Error(); | |
} | |
return valType; | |
} | |
const t = typeof val; | |
switch (t) { | |
case 'boolean': | |
case 'number': | |
case 'string': | |
// TODO: Ideally, this cast wouldn't be necessary! | |
// It ties this code to the StringValueType type union. | |
// It'd be nice to statically verify we've exhaustively checked. | |
return t as StringValueType; | |
default: | |
throw new Error('Should never happen!'); | |
} | |
} | |
// These should not compile (but undefined and null do when `--strictNullChecks` isn't enabled): | |
parse(); | |
parse(undefined); | |
parse(null); | |
parse({}); | |
parse([]); | |
parse(parse); | |
// These should compile, and the type should be correctly inferred! | |
let strType = parse(''); | |
let numType = parse(0); | |
let boolType = parse(false); | |
let verifyStrType: 'string' = strType; | |
let verifyNumType: 'number' = numType; | |
let verifyBoolType: 'boolean' = boolType; | |
// These should not: | |
strType = parse(0); | |
numType = parse(false); | |
boolType = parse(''); | |
// These should compile, and the type should be correctly inferred too! | |
strType = parse(null, 'string'); | |
numType = parse(null, 'number'); | |
boolType = parse(null, 'boolean'); | |
verifyStrType = strType; | |
verifyNumType = numType; | |
verifyBoolType = boolType; | |
// These should not: | |
strType = parse(null, 'boolean'); | |
numType = parse(null, 'string'); | |
boolType = parse(null, 'number'); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment