Skip to content

Instantly share code, notes, and snippets.

@aseemk
Last active November 13, 2016 15:32
Show Gist options
  • Save aseemk/2ac1dfbc08bfd18b92da7d9fc8b0a838 to your computer and use it in GitHub Desktop.
Save aseemk/2ac1dfbc08bfd18b92da7d9fc8b0a838 to your computer and use it in GitHub Desktop.

Revisions

  1. aseemk revised this gist Nov 13, 2016. 1 changed file with 1 addition and 2 deletions.
    3 changes: 1 addition & 2 deletions typescript-static-and-runtime-typing.ts
    Original file line number Diff line number Diff line change
    @@ -29,8 +29,7 @@ function parse(val: StaticValueType | null, valType?: StringValueType): StringVa
    }
    }

    // These should not compile (but undefined and null do
    // when `--strictNullChecks` isn't enabled):
    // These should not compile (but undefined and null do when `--strictNullChecks` isn't enabled):
    parse();
    parse(undefined);
    parse(null);
  2. aseemk revised this gist Nov 13, 2016. No changes.
  3. aseemk created this gist Nov 13, 2016.
    65 changes: 65 additions & 0 deletions typescript-static-and-runtime-typing.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,65 @@
    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');