11 ms·
While TypeScript isn't perfect, it surely is a major step forward compared to plain JS! Newer features like conditional types and mapped types open up new possi
by nikolasburk 7y ago
While TypeScript isn't perfect, it surely is a major step forward compared to plain JS! Newer features like conditional types and mapped types open up new possibilities. My colleague actually recently gave a fantastic talk about these advanced features at the TS Berlin Meetup, highly recommended watch if you want to see what it's like pushing the boundaries of TypeScript: https://www.youtube.com/watch?v=PJjeHzvi_VQ https://www.youtube.com/watch?v=PJjeHzvi_VQ
- vorticalbox 7y agoStill compiles Down to js where you lose all type checking. Have you ever looked at a compiled js file? Things like spreading objects I to each other {...a,...b} End up being a nest object assign which is actually slower than spreading.
- skrebbel 7y agoSlower and more widely supported. Also iirc you can set the compile target to esnext and it will compile to the object spread expression.
- mixedCase 7y agoChecks don't need to be in the JS, they just need to be there at compile time. No differently than a binary generated by Haskell; and you have source maps to replace debugging symbols too. And as mentioned by another user, you can choose your compile target to a specific version of JS which does support object spreading.
- hopia 7y agoActually, Haskell compilation produces more type information available at runtime than Typescript's compiler does. For example, algebraic data types turn into tagged unions at runtime on Haskell, allowing pattern matching to operate on them. Whereas on Typescript the compilation process erases all this information, making it impossible to evaluate many such expressions. There are multiple 3rd party solutions to this, such as: https://github.com/pelotom/runtypes https://github.com/pelotom/runtypes
- mixedCase 7y ago> algebraic data types turn into tagged unions at runtime on Haskell How does that work? I know next to nothing about the GHC, but in Haskell I would assume some tag is associated with each constructor (probably an integer) for the ADT and that the actual pattern matching gets compiled down to simple comparisons to either that integer or the right function for the more complex cases (pattern matching strings and other values). TypeScript essentially does that, except that the tags are not going to be optimized by the compiler (they will remain strings if the dev uses them), and the "pattern matching" is just regular conditional checks (if, ternary or switch) with even the exhaustiveness check being done as a manual hack introduced by the dev and checked at compile-time (the else or default case assigning the value to the never type). As for runtime values, Haskell also needs to validate types when deserializing, although that will be done by the deserialization libraries such as Aeson instead of deserializing and then optionally validating like in TS.
- hopia 7y agoYes, you're right, it should be an integer comparison check ultimately. > TypeScript essentially does that, except that the tags are not going to be optimized by the compiler What do you mean by this? Typescript erases type information during compilation. So you would not be able to emulate pattern matching against types on TS. Or you could if you manually added some common tag to every single data type like interface. Or are you talking about just compile-time type checking on TS?
- mixedCase 7y ago> Or you could if you manually added some common tag to every single data type like interface. This is how you emulate them, I took it for granted and neglected to explicitly mention this is a moderately popular convention in TypeScript (those are the tags I referred to). fp-ts for example uses it all over the place. With this the end result is essentially the same with compile-time type-safety for everything, and compiled down to an untyped binary or an untyped JS blob.
- thelazydogsback 7y ago
- valand 7y agofriendly tips: runtime type checks are available https://github.com/gcanti/io-ts https://github.com/gcanti/io-ts https://github.com/pelotom/runtypes https://github.com/pelotom/runtypes
- krowokoliz 7y agoWhy would you want runtime checks over static checks? The one thing I can think of is type asserting input from other js code, but surely you just want that on the entry function to your code, not in the internal bits.
- valand 7y agoTS compiled can still be faulty if the app is injected with data of different type Runtime type checks is the lost link between static checks at compile time and arbitrary i/o data type in compiled js code. You define a type in a similar way you would define TS types. At compile time it would give you the typescript type checks. At runtime it will help you determine if data has the correct type exactly as your typescript app expected. There is extra work though, handling error if there is a faulty data type
- Scooty 7y agoRuntime type checking is necessary to ensure data received from untrustworthy sources matches compiletime types.
- michaelcampbell 7y ago> Still compiles Down to js where you lose all type checking. Haskell compiles down to machine code, so...
- filleduchaos 7y agoThis is an often expressed sentiment that I feel misses the point by a mile, which is that Haskell (as well as other languages in its class) _forces_ you to actually write programs that are soundly typed at compile time. TypeScript very explicitly does not, instead taking an approach to typing that's more in line with languages like Java or C# (which rely on both compile time and runtime type checking to enforce a program's types) but failing to provide the runtime type checking to back it up. And even that wouldn't be so much of a problem if it didn't compile to a language as dynamically and weakly typed as JavaScript.
- michaelcampbell 7y ago> I feel misses the point by a mile I disagree. The point to which I refer was stating that because language A with type safety of some degree compiled to another form B without it obviates A's type safety altogether. The destination isn't the point; it's the compilation of the beginning.
- deleted 7y ago[deleted]
- bradstewart 7y ago> Still compiles Down to js where you lose all type checking. While true, what's the point of this argument? You cannot get language-level runtime typechecking in the browser. At all. With any toolchain.
- filleduchaos 7y agoSeveral compile-to-JS projects do ship a type-checking (amongst other things) runtime to the browser.
- leshow 7y agoIt's better to do it statically and save yourself the overhead at runtime. I don't see why you'd even want it the other way.
- reificator 7y ago> Still compiles Down to js where you lose all type checking. Yes and C still compiles to assembly with no type checking. What's your point?
- filleduchaos 7y agoC is an infamously unsafe language, so the question might rather be what _your_ point is.
- reificator 7y ago> C is an infamously unsafe language, so the question might rather be what _your_ point is. Feel free to insert Rust or Haskell or whatever your language of choice is in place of C and my point remains the same. Sure you can include type information inside the assembly output and some sort of runtime code to handle that, but that doesn't change the fact that your compile target has no type system. Typescript could do the same if they desired, and in fact I think they offer the option. Compiling a language with a type system to a language without is not a knock against that language's type system. Compiling typescript's decently comprehensive/expressive compile-time type system to javascript's basic runtime type system actually seems like a step up compared to a lot of other compilation targets.
- filleduchaos 7y agoLike I have said elsewhere, Haskell and Rust and other such languages actually force you (to varying degrees) to write programs that are soundly typed at compile time. TypeScript explicitly doesn't, and instead treats program types in a way that's far more like Java or C# (which rely on both compile time and runtime type checking to enforce a program's types, and even at that are not entirely sound) without the runtime type checking to back it up. > Typescript could do the same if they desired, and in fact I think they offer the option. They very explicitly do not and have stated severally that it is not within the goals of the project to do so, which is something anyone actually familiar with the language should know. > Compiling a language with a type system to a language without is not a knock against that language's type system When you don't cherry-pick statements out of context, the point of what I said becomes rather obvious; if a language doesn't actually guarantee type safety at compile time, having a primary compilation target that takes a fascinatingly lax approach to data types is objectively worse (wrt type safety) than having one that's more strict.
- dragonwriter 7y ago> Still compiles Down to js where you lose all type checking. And C, Rust, Haskell, etc., all compile down to native code where you lose all type checking, so what? Outside of compiler bugs, what is statically proven at compile time doesn't change at runtime. (Yes, C also has a notoriously loose and abusable compile time type system, but that's a different issue.) > Things like spreading objects I to each other > {...a,...b} > End up being a nest object assign which is actually slower than spreading. Yes, if you use the default target (ES3), typescript emits JS compatible with downright ancient browsers which is super portable at the cost of being less efficient than targeting modern JS features, like spread syntax which was introduced in ES6. You can also set the target to newer ECMAScript levels, including “ESNext”, at the cost of compatibility.