4 ms·
Not really, I provided these examples a couple weeks ago on another HN thread. TypeScript is simply unsound. https://www.typescriptlang.org/play/?#code/MYewdg
by debugnik 10mo ago
Not really, I provided these examples a couple weeks ago on
another HN thread. TypeScript is simply unsound.
https://www.typescriptlang.org/play/?#code/MYewdgzgLgBAllApgWwgLhmArsgRogJwG0BdGAXhiIGYSBuAKFEllwJAGtEwBJJVDAApseQgB9oBOGADmASlIV4-CIzadufFBAB0ABywQAFoIBEAMxAhTcxs2iYQUAHI58BDCPdKE2ogEZ6JnAIEAAbRB0wkBlhJ1dRAlsGIA https://www.typescriptlang.org/play/?#code/MYewdgzgLgBAllApg...
https://www.typescriptlang.org/play/?#code/DYUwLgBAHgXBB2BXAtgIxAJwNwFgBQAxgPbwDOkwRA5hALwQAUAlHQHwTFlGgB0lVDKE1x5+zEUA https://www.typescriptlang.org/play/?#code/DYUwLgBAHgXBB2BXA...
- jstanley 10mo agoPerfect examples of the kind of thing I'm talking about, thank you.
- LordN00b 10mo agoIn 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 10mo agoFor 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
- jstanley 10mo agoIf 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 10mo agoBecause 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.
- debugnik 10mo agoFirst 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.
- swiftcoder 10mo ago> The second is a delegate, that will be triggered at any point during runtime. How can the compiler know what x will be? x is clearly defined to be a number. The compiler should produce an error if the delegate captures x before it has a value assigned.
- sandblast 10mo agoAren't these bugs that could be "simply" reported and fixed? Or maybe those would get a label "not a bug" attached by the TS creators for some reason?
- debugnik 10mo agoBoth are by design. Array covariance is a common design mistake in OOP languages, which the designer of TypeScript had already done for C# but there they at least check it at runtime. And the latter was declared not-a-bug already IIRC. TypeScript designers insist they're ok with it being unsound even on the strictest settings. Which I'd be ok with if the remaining type errors were detected at runtime, but they also insist they don't want the type system to add any runtime semantics.
- sandblast 10mo ago"By design", for me, doesn't say that it can't be changed — maybe the design was wrong, after all. Would it be a major hurdle or create some problems if fixed today?