4 Unconventional Ways to Cast in Typescript

26 points by polywolf


abbeyj

Can "Unconvention 2" be simplified down to the following?

const mutation = <A, B,>(a: A, b: B): B => {
    const obj = { field: b };
    const obj2: { field: A | B } = obj;
    obj2.field = a;
    return obj.field;
};

No need for an inner function.

jez

The soundness problems in TypeScript were why I was always rooting for Flow. For example:

Flow had its own problems (e.g., the editor tooling for Flow compared disfavorably to TypeScript), but soundness was always squarely a win in Flow.

schuelermine

Is there any real consensus on what the goal of a type system is?

Because very clearly, “unsound” systems like the TypeScript type system, or the Python type system, are still useful for helping catch errors in code.

And also in the other direction—one way of defining the purpose of type systems is to say they classify program values in order to ensure “wrong” things in the language don’t happen. But then what do newtypes do? They prevent errors, but these errors aren’t formally errors.

Is there some theory about what type systems actually do?

lazytype

My sense is that most sources of unsoundness in TypeScript can be exploited into an unsafe cast. Here's one using Object.assign and never type.

function cast<A, B>(value: A): B {
    return Object.assign(
        { field: () => { throw new Error(); } },
        { field: () => value },
    ).field();
}