Skip to content

Instantly share code, notes, and snippets.

@aseemk
Last active November 13, 2016 15:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aseemk/2ac1dfbc08bfd18b92da7d9fc8b0a838 to your computer and use it in GitHub Desktop.
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
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