Remix.run Logo
mckirk 8 hours ago

I generally do this via a `throw UnsupportedValueError(value)`, where the exception constructor only accepts a `never`. That way I have both a compile time check as well as an error at runtime, if anything weird happens and there's an unexpected value.

jstanley 4 hours ago | parent | next [-]

The fact that there can be runtime type errors that were proven impossible at compile time is why I will never enjoy TypeScript.

thomasikzelf 2 hours ago | parent | next [-]

If Typescript is javascript with types bolted on, Rescript is javascript with types the way it should have been. Sound types with low complexity. https://rescript-lang.org/

ownagefool 2 hours ago | parent | prev | next [-]

Agree wholeheartedly.

Writing TypeScript is better than JavaScript, but the lack of runtime protection is fairly problematic.

However, there are libraries such as https://zod.dev, and you can adopt patterns for your interfaces and there's already a large community that does this.

eitland 2 hours ago | parent | prev | next [-]

TypeScript isn't primarily meant to be enjoyed.

It is meant to be a much better alternative to Javascript while dealing with the fact that the underlying engines use and existing programmers were used to Javascript.

That said I absolutely enjoy TypeScript, but that might be because I suffered from having to deal with Javascript from 2006 until TypeScript became available.

virtue3 an hour ago | parent [-]

I have the exact same reason I enjoy typescript - raw dogging js before was an absolute nightmare of testing every single function for every possible value that might be thrown in and being able to handle shit data everywhere.

god-awful code.

Defletter 3 hours ago | parent | prev | next [-]

Isn't that not necessarily out of the ordinary though? What if there's a cosmic ray that change's the value to something not expected by the exhaustive switch? Or more likely, what if an update to a dynamic library adds another value to that enum (or whatever)? What some languages do is add an implicit default case. It's what Java does, at least: https://openjdk.org/jeps/361

jstanley 2 hours ago | parent [-]

> What if there's a cosmic ray that change's the value to something not expected by the exhaustive switch?

I could forgive that.

The TypeScript case is more like "what if instead of checking the types we just actually don't check the types?".

jaapz 2 hours ago | parent | prev | next [-]

It's way better than having to write untyped JavaScript though

locknitpicker 3 hours ago | parent | prev | next [-]

> The fact that there can be runtime type errors that were proven impossible at compile time is why I will never enjoy TypeScript.

The "impossibility" is just a trait of the type definitions and assertions that developers specify. You don't need to use TypeScript to understand that impossibilities written in by developers can and often are very possible.

jstanley 3 hours ago | parent [-]

My first introduction to TypeScript was trying to use it to solve Advent of Code.

I wrote some code that iterated over lines in a file or something and passed them to a function that took an argument with a numeric type.

I thought this would be a great test to show the benefits of TypeScript over plain JavaScript: either it would fail to compile, or the strings would become numbers.

What actually happened was it compiled perfectly fine, but the "numeric" input to my function contained a string!

I found that to be a gross violation of trust and have never recovered from it.

EDIT: See https://news.ycombinator.com/item?id=46021640 for examples.

macguillicuddy 13 minutes ago | parent [-]

No tool is perfect. What matters is if a tool is useful. I've found TypeScript to be incredibly useful. Is it possible to construct code that leads to runtime type errors? Yes. Does it go a long way towards reducing runtime type errors? Also yes.

triyambakam 3 hours ago | parent | prev [-]

That scenario is usually either misuse of escape hatches (especially at API boundaries) or a misunderstanding of what Typescript actually guarantees.

debugnik 3 hours ago | parent [-]

Not really, I provided these examples a couple weeks ago on another HN thread. TypeScript is simply unsound.

https://www.typescriptlang.org/play/?#code/MYewdgzgLgBAllApg...

https://www.typescriptlang.org/play/?#code/DYUwLgBAHgXBB2BXA...

jstanley 2 hours ago | parent | next [-]

Perfect examples of the kind of thing I'm talking about, thank you.

LordN00b an hour ago | parent | prev [-]

In the first example you deliberately create an ambiguous type, when you already know that it's not. You told the compiler you know more than it does. The second is a delegate, that will be triggered at any point during runtime. How can the compiler know what x will be?

bspammer an hour ago | parent | next [-]

For the first one, the compiler should not allow the mutable list to be assigned to a more broadly typed mutable list. This is a compile error in kotlin, for example

    val items: MutableList<Int> = mutableListOf(3)
    val brokenItems: MutableList<Any> = items
debugnik an hour ago | parent | prev | next [-]

First example: you're confusing the annotation for a cast, but it isn't; it won't work the other way around. What you're seeing there is array covariance, an unsound (i.e. broken) subtyping rule for mutable arrays. C# has it too but they've got the decency to check it at runtime.

Second example: that's the point. If the compiler can't prove that x will be initalised before the call it should reject the code until you make it x: number|undefined, to force the closure to handle the undefined case.

jstanley an hour ago | parent | prev [-]

If it only works when you write the types correctly with no mistakes, what's the point? I thought the point of all this strong typing stuff was to detect mistakes.

macguillicuddy 5 minutes ago | parent [-]

Because adding types adds constraints across the codebase that detect a broader set of mistakes. It's like saying what's the point of putting seatbelts into a car if they only work when you're wearing them - yes you can use them wrong (perhaps even unknowingly), but the overall benefit is much greater. On balance I find that TypeScript gives me huge benefit.

Klaster_1 3 hours ago | parent | prev | next [-]

Same here, you can also use the same function in switch cases in Angular templates for the same purpose. Had no idea you could achieve similar with `satisfies`, cool trick.

mquander 7 hours ago | parent | prev | next [-]

That's great, I'm going to use that one in the future.

rezonant 7 hours ago | parent | prev [-]

That's very clever!