Hacker News new | ask | show | jobs
by pavel_lishin 1708 days ago
> In practice you'd have someone that understands this set it up once, and then document its usage for others, maybe document the implementation to make it easier to modify later.

In practice, that someone then leaves the company, leaving this nightmare underfoot.

> The TS compiler is surprisingly good at giving you good readable error messages as well when your code violates these advanced types

Only if you're that original person who understands it! I would still have no idea what is happening, no matter how clear.

2 comments

The sample type code mentioned above will give the following error on the TypeScript Playground (https://www.typescriptlang.org/play):

  "Type '{ foo: number; }' is not assignable to type 'B'.
    Property 'baz' is missing in type '{ foo: number; }' but required in type '{ foo: number; baz: number; }'."
I've had the compiler emit errors much like the following for way more complicated types that combined several of these kinds of structures together to form much more bespoke type checks (reproduced from memory, so I'm not 100% certain on the error or use case):

  const e = form.email
  ^
  ERROR: "email" is not in '"name" | "firstname" | "lastname" | "e-mail" | "birthdate" | "password"'
The thing to note here is that it often doesn't expose the details of the implementing type and underlying (admittedly complicated) type system primitives at all to users. That said, I'll have to be honest and say that I have seen it throw much more difficult to understand nested errors referring to the underlying type implementation when I was working on the type system itself to create stricter type checks for functionality that was previously unchecked (i.e. treated as "any" by the compiler).

The other thing to note is that these things are really only doing type checking. If it becomes troublesome and it does start to spit out type errors incorrectly, throw unreadable errors, or otherwise become a maintenance burden, these types are not particularly difficult to remove, and by removing them you won't break your code. Consider that to be the equivalent of removing a linting rule or no longer requesting a review from a colleague. Though it's probably a good idea to document how to remove these advanced checks for when people find them annoying when someone leaves ;)

Incorrect type checking implementation is probably the biggest problem with these things getting complex, though. If your type check is incorrectly throwing errors for implementations that don't contain any errors at all, that's going to set you back a lot!

Isn't this true for any abstraction, though? If the person who wrote it is inaccessible, you have to understand it by reading the source.
Sure. But this is easier to understand, albeit means repeating code:

    class B {
        foo: number;
        bar?: number;
        baz: number;
    }
I know these are toy examples, and I'm sure there are reasons why in the real world you'll be modeling things where this is not a good option. But I'd really need to be convinced that the CRUD webapps a lot of us write actually benefit from having this in our source code.