1. 17
  1. 11

    Be careful with this feature and type guard functions - if they’re incorrect or rot they can introduce big lies in your type safety, since theres no checking that the type assertion actually proves its signature. A lot of people are surprised by this! These functions can look safe but are also long, elaborate casts.

    At Notion we use a utility higher-order function to construct type assertion/guard functions in a way that requires you to type-narrow/prove or explicitly cast. if you want to write a type guard function that declares input I is O, you need to return { true: O }.

    1. 3

      Yes, agree. Trying to come up with ways to keep my assertion functions and the actual data in sync is a constant drain on my “ambient computing power”. We really need a version of TS types that lives in runtime to use in unit tests.

      1. 2

        Is there no good design by contract library in TS/Js?

        1. 1

          I doubt it, even Eiffel’s DBC is pretty weak, and AFAIK it’s still the poster-child. But I don’t want to repeat ceremony in my working code, like some sort of frankenJava on roids, I just want some background process run during build that ensures my isFoo code stays in-line with my definition of Foo, which unfortunately isn’t available at run-time, even in tests.

          1. 1

            Interesting. Why do you think Eiffel’s DBC is weak? I’m toying around with a DBC library for Elixir. What kind of information you would like not erased at run time?

            1. 1

              Weak is probably the wrong word. Limited, is better. But I have only read the book through once, there wasn’t any way to get tooling without paying up-front at the time so I regretfully put it aside back then and never used it in anger.

              I’m not 100% certain I want the Typescript definitions to be available to application code at runtime, but I would very much like them to be available for unit testing, as well as codegen. You can call TSC as a lib, but you get back an AST rather than something more akin to Java’s reflection API, and it’s not very easy to grok / navigate at the AST level.

      2. 1

        we use a utility higher-order function to construct type assertion/guard functions in a way that requires you to type-narrow/prove or explicitly cast

        Can you share more about this approach? What does this look like in practice?

        1. 1

          Would you kindly give an example for someone who’s good with JS but still learning TS?

        2. 3

          This is awesome. The TypeScript type system is one of my favorite things right now.

          1. 3

            I love that it’s a type system build to describe the chaos of real world use of an untyped language, rather than something proscriptive coming from academia or something convenient for compiler writers to implement

          2. 3

            I completely missed asserts and have still been using Boolean type guard functions for this. You gotta read those release notes every time; TypeScript moves fast.

            1. 1

              So the immediate motivation of this feature is to make unit testing cleaner? In production code I’d usually extract the type assertion by factoring out a function that returns the narrowed value, rather than adding a side-effectful assertion, but tests tend to be written the latter way.