5 ms·
The fact that there can be runtime type errors that were proven impossible at compile time is why I will never enjoy TypeScript.
by jstanley 11mo ago
The fact that there can be runtime type errors that were proven impossible at compile time is why I will never enjoy TypeScript.
- Defletter 11mo agoIsn'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 https://openjdk.org/jeps/361
- jstanley 11mo ago> 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?".
- tshaddox 11mo agoThis is how all static type checking works. What programming language do you have in mind that does static type checking and then also does the same type checking at runtime? And what would you expect this programming language to do at runtime if it finds an unexpected type?
- RussianCow 11mo agoI think the point is that other languages make guarantees that ensure you don't have to do any runtime checking. In TypeScript, it's far too easy (and sometimes inevitable) to override the type checker, so some poor function further down into the codebase might get a string when it expects an object, even though there are no type errors.
- vips7L 11mo agoCompiler exhaustion is such a useful feature. I can’t believe TS doesn’t have it.
- triyambakam 11mo agoThat scenario is usually either misuse of escape hatches (especially at API boundaries) or a misunderstanding of what Typescript actually guarantees.
- debugnik 11mo agoNot 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 11mo agoPerfect examples of the kind of thing I'm talking about, thank you.
- LordN00b 11mo 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 11mo 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 11mo 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.
- locknitpicker 11mo ago> 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 11mo agoMy 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 https://news.ycombinator.com/item?id=46021640 for examples.
- macguillicuddy 11mo agoNo 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.
- swiftcoder 11mo ago> No tool is perfect. What matters is if a tool is useful Some tools are more perfect and more useful than others. Typescript's type system is very powerful, but without strict compile-time enforcement you still spend a lot of effort on validating runtime weirdness (that the compiler ought to be able to enforce).
- macguillicuddy 11mo ago
- ownagefool 11mo agoAgree 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 https://zod.dev, and you can adopt patterns for your interfaces and there's already a large community that does this.
- Degorath 11mo agoCould you please elaborate on "patterns for your interfaces"?
- ownagefool 11mo agoSure. You tend to think about the edges of your application. 1. Router Tanstack Router: Supports runtime validation libraries such as z0d. So I have routes such as example.com/viewer/$uuid/$number, it should 400 if those aren't actually validate uuid and numbers. React Router: Supports Types, but every type is a string because, well, they technically are, but this isn't useful in practice in my opinion. There are 3rd party libs such as: https://github.com/fenok/react-router-typesafe-routes https://github.com/fenok/react-router-typesafe-routes 2. API Lets say you're making your API public to clients you can't trust to send the correct data ( which probably also includes your own client ). https://www.npmjs.com/package/express-openapi-validator https://www.npmjs.com/package/express-openapi-validator This library advertises validating both your input and your output 3. State https://github.com/pmndrs/zustand/discussions/1722 https://github.com/pmndrs/zustand/discussions/1722 4. Database https://www.npmjs.com/package/prisma-zod-generator https://www.npmjs.com/package/prisma-zod-generator 5. Forms https://medium.com/@toukir.ahamed.pigeon/react-hook-form-with-zod-validation-a-complete-guide-with-typescript-aacbcb370a8b https://medium.com/@toukir.ahamed.pigeon/react-hook-form-wit... 6. ENV https://jfranciscosousa.com/blog/validating-environment-variables-with-zod/ https://jfranciscosousa.com/blog/validating-environment-vari... Obviously checks on the agent are primarily a DX/UX thing, whilst checks on the server step are also security controls.
- CharlieDigital 11mo agoZod is quite unpleasant to use, IME, an has some edge cases where you lose code comments. From experience, we end up with a mix of both Zod and types and sometimes types that need to be converted to Zod. It's all quite verbose and janky. I quite like the approach of Typia (uses build-time inline of JavaScript), but it's not compatible with all build chains and questions abound on its viability post Go refactor.
- thomasikzelf 11mo agoIf 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/ https://rescript-lang.org/
- intellix 11mo agoThat syntax is so alien to me as a JS/TS developer. I mean coffeescript was as well until JS slowly introduced it all. It would be cruel for me to force ReScript onto the team because they'd all need to reskill. I could only use it for a private project and then hire exclusively for it afterwards
- thomasikzelf 11mo agoReally, that is surprising to hear. There are a couple of differences but most of the syntax looks the same to me, what part do you find alien? The reskill problem is of similiar difficulty with learning a new framework I think. Especially because the language is rather simple compared to typescript (which is also its strength). I do understand it is an uphill battle. The whole nobody get's fired for choosing IBM thing. The language is still unproven in the general perception. I do think that when it comes to libraries and frameworks I see a lot of developers choose new unproven stuff, more then they do languages.
- cess11 11mo agoDoes this have a relation to Reason/Reason ML?
- dcre 11mo ago“ReScript is a rebranding of BuckleScript and Reason” https://v11.rescript-lang.org/docs/manual/latest/migrate-to-new-syntax https://v11.rescript-lang.org/docs/manual/latest/migrate-to-... https://rescript-lang.org/blog/bucklescript-is-rebranding/ https://rescript-lang.org/blog/bucklescript-is-rebranding/
- jaapz 11mo agoIt's way better than having to write untyped JavaScript though
- eitland 11mo agoTypeScript 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 11mo agoI 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.
- plaguuuuuu 11mo agoAs a C# dev, backend typescript is fantastic and the type system is light years ahead of C# in expressivity. But the learning curve... no shit.
- Normal_gaussian 11mo agoTypeScript is neither sound nor complete and was defined that way, beating out other competitors that were sound and/or complete. What I mean to say is - TypeScript isn't proof.