6 ms·
There is a good reason for not doing this. Typescript would become some kind of runtime on top of JavaScript. A new language that compiles to JavaScript. Curren
by andix 3y ago
There is a good reason for not doing this. Typescript would become some kind of runtime on top of JavaScript. A new language that compiles to JavaScript. Currently TS is only JavaScript with type annotations.
There are many languages that compile to JavaScript. Pick one of them and use it!
And I have the feeling, that people who want runtime typed Typescript would rather like to write Java/OOP style code instead of JavaScript. But JavaScript is a dynamically typed language, and that's also nice. Be happy with what you have!
- shortrounddev2 3y agoThe reason we want typescript to have java-like features is because we work on teams which have decided, outside of our control, that we are going to write our backend in JS/TS simply because it's easier for the bootcamp grads to transition to backend since they already know JS on the frontend. If we wrote our backend in Java, it would require the bootcamp grads to learn a new language, which they're not prepared to do. Choosing typescript or javascript on the backend is not about choosing the right tool for the job (because they are objectively not the right tool for backend development). It is mostly about minimizing the cost of our labor sourcing As such, RTTI would make typescript go from a compromise language (we use it because we are stuck in the JS ecosystem, not because it's a good tool) to a legitimately useful backend language (We use it because it has the right features for the use-case) If I could choose what language we use on the backend, I would leave the JS ecosystem entirely and write everything in .Net. But it's difficult to find .Net developers since every bootcamp these days produces react developers
- andix 3y agoSo you want TypeScript to be Java, but you don't want to use Java, because your developers only know TypeScipt. Sounds like an unsolvable problem.
- shortrounddev2 3y agoThe solution is to pile features onto typescript that were never intended to be there, the same way we have done with Javascript, HTML, CSS, and HTTP. None of these things are pure, and all of them have been ravaged by competing interests and committees who were all making financially driven decisions when writing the standards. It would be best to abandon javascript and typescript as backend languages. I don't mind them on the frontend because a typescript compiler is useful when the application you're writing is originating data and not receiving it. And javascript does DOM manipulation admirably. However, we live in a world where humans are more expensive than computers. If I had my way, we'd write C# backends and Angular/Typescript frontends, but that's not the world we live in. Everything has to be JS because most people employed as "software engineers" are not truly very good at their jobs
- kristiandupont 3y agoI, on the other hand, would pick TS over .NET or Java any day. But I am sure you will conclude that it can only be because I am no good at my job.
- shortrounddev2 3y agoNo, I'm sure you have your reasons, but deserializing and validating is much more painful in typescript than it is in .Net or Java so I'm not sure why you would choose that
- fzeindl 3y agoYou can use Kotlin and compile to JavaScript. It's type system is better and the standard library greater scnr
- lf-non 3y agoKotlin's type system works great for interop with a nominally typed lang like java but for interop with a dynamically typed lang like js and myriad of its libs not designed with type safety in mind, structural typing is far more convenient.
- andix 3y agoExactly. Pick whatever language you like. There are many more options.
- booi 3y agoThis is the way. Best of both worlds although using js libraries is kind of a pain
- asherah 3y agotypescript enums exist and are compiled to javascript (other than const enums)
- andix 3y agoAnd that's one of the features of typescript that really sucks. String union types work so much better.
- moystard 3y agoWhy does typescript enum really suck?
- Waterluvian 3y agoThere’s a ton written about this if you search for “typescript enums.” I just finished removing them from a major project. Here’s a few of my personal notes: 1. They don’t play well with duck typing. (Eg. show me a subset of an enum) 2. They require an import every time you want to utilize them. 3. They are pretty wordy compared to union strings. 4. Their string value version encourages misuse as a key-value pair. 5. Unless you use the string value version, they suck to debug because logs just show 0,1,2,3.
- WorldMaker 3y agoAnother one: they conflate Type and (Locator) Instance in a unique way that just about nothing else in TS does. Those are two very different things with the same name with Typescript's (antiquated) enums. There are too many ways to accidentally import/redeclare/rescope the Type of an enum so that TS "knows" the Type, but because that type (generally) has the same "name" as the most likely (Locator) Instance it assumes the same access applies leaving runtime errors behind when that Instance isn't actually imported/available. Typescript has no easy way to tell the difference between access to the Type isn't access to the (Locator) Instance (nor vice versa). Reasoning about those runtime errors or preventing them is additionally tough for people too because of the same "name" problem for two different things. This is something that's painfully hard to avoid in cases where you are trying to encapsulate an API's Types separate from its imports/exports because they might be introduced or manipulated at runtime (plugins, sandboxes, proxies, etc). Unfortunately, this is also too easy to accidentally do even when you aren't intentionally doing something complicated like that (trying to generate automated .d.ts files in a bundling toolchain, for example, when APIs are in the boundary space between unintentional public API and internal tree-shaking or optimized symbol renaming).
- joshmarinacci 3y agoDynamically typed means I can look up the type of an object at runtime. JavaScript lets us do this with classes/prototypes. Since TypeScript adds types and enums and interfaces, why can’t it let us look up those at runtime too? It would seem to fit with the way JS works.
- Arainach 3y agoFor any sufficiently large project, dynamically typed languages are not nice, they are a series of interweaved disasters consisting of constantly tripping over what you thought was your feet but is actually NaN and trying to fall forward rather than collapsing entirely. In every workflow I've seen, TypeScript is already a language that gets compiled to JS. It might as well take full advantage.
- andix 3y agoTypescript is not really compiled to JS, only the type annotations are removed. To make dynamically typed languages nice for bigger projects we have typescript for type annotations (it's does not make it a statically typed language!). It is there, it is used, it scales and it works. If your type script project "collapses entirely", it's probably not the languages fault.
- random_mutex 3y agoReasonML
- deleted 3y ago[deleted]
- dimitrios1 3y agoReasonML suffered tremendously when the community split and went off to do ReScript. I don't think either have recovered the original luster.
- a_wild_dandan 3y agoI'm misunderstanding your reasoning here. TS is already a new (superset) language which compiles to JS. Runtime types solve the problem of maintaining two duplicate, separate type systems -- one for compilation, one for validating data. I'm not seeing how that's related to OOP. For instance, my preferred workaround lib for this problem, `io-ts`, leans hard on functional programming.
- PaulHoule 3y agoYeah but just because types exist at compile time doesn't mean they exist at run time. For instance with Generics in Java a List<String> is the same as a List<Integer> at run time, the compiler can enforce rules that let you add a String to one but not add a String to the other but the runtime has no idea. This has various negative consequences but it also let them retrofit generic collections on top of the old collection implementation in Java unlike the disaster in .NET where both had to coexist for years. Similarly C compiles to machine code and in machine code there are just memory locations and registers, types are implicit in how you use those things but not spelled out explicitly. C++ does have RTTI but is one of the many open pits, like Exceptions, in C++. Typescript types are the same way, once the compiler has done its type checking you know the code is going to behave according to the type system even if the types have been "erased".
- einrealist 3y agoJava's generic type information (aka parameterized types) is available at runtime through reflection.
- PaulHoule 3y agoDepends on the situation. If you just make an ArrayList<X> (for some specific class X) you can call getClass() on that object and see it is an ArrayList but you cannot find out about the X. If you make an ArrayListX that is not generic but extends ArrayList<X> it is possible to see the type parameter that was extended, the same is true for implementations. There are other kinds of type unerasure that you can use w/o the language supporting it explictly, such as you could pass the type parameter X.class into the constructor and put it in a field so that you could call some method like getContainedClass() and get a copy of X. Now the introspection/reflection API does have support for talking about parameterized generic types that doesn't mean that information always exists at runtime. I worked on a crazy project where I did a lot of fighting with ordinary types and parameterized types and unerasing types by rewriting the names of methods to avoid conflicts, if you have methods like A doSomethingTo(B) A doSomethingTo(C) you can rewrite these to Expression<A> doSomethingToB(Expression<B>) Expression<A> doSomethingToC(Expression<C>) but you can't have an overload that takes two differently parameterized expressions, this lets you write Java code in a lisp-like syntax that can be metaprogrammed on: https://github.com/paulhoule/ferocity/blob/main/ferocity-stdlib/src/test/java/com/ontology2/ferocity/stdlib/TestFierceLambda.java https://github.com/paulhoule/ferocity/blob/main/ferocity-std... that project got me thinking a lot about the various ways types manifest in Java and I made the discovery that when you add Expression types you practically discover an extended type systems where there are many things that are implied by the existence of ordinary Java types.
- whalesalad 3y agoYou can have both. This is the beauty of lisp - https://en.wikipedia.org/wiki/Homoiconicity https://en.wikipedia.org/wiki/Homoiconicity But in all seriousness you can gain reflection without a runtime. Just expose the types as data. Seems foolish to not do something like this. Particularly when you look at the lengths so many devs have gone to try and replicate it.
- armchairhacker 3y agoNot necessarily. Consider const fooType = generateTypeInfo!<Foo>(); Where `generateTypeInfo!` is a macro that expands to a JS object encoding the “Foo” type (e.g. if `Foo` a record type, `fooType` will be a record with its encoded field types). It still compiles to readable JavaScript. What this macro does break is that TS = JavaScript with type annotations, and all you need to do to compile is remove those annotations (excluding enums, but they are all-but-deprecated and obsoleted by string unions) without even type-checking. Since now you also need to expand the `generateTypeInfo!`, which requires actually computing the structural type of `Foo` (and if you want any sort of nominal type metadata, that too). And that’s still a problem because type-checking is slow, but removing the annotations is fast. If there’s a limited way to resolve types for these annotations which restricts the resolution scope, that would be a good candidate. —- There's also more issues with TypeScript having a separate runtime besides it not being JavaScript. TypeScript types are structural, so they currently are available at runtime: to determine an object’s type, inspect its structure. Anything more and you quickly run into non-trivial cases being literally impossible: if you want erased nominal information like whether a string is part of a string union, TypeScript’s type system is Turing complete; and if you want the nominal type name, implicit structural conversions mean that once a value leaves its annotated cast or definition it’s effectively undefined.
- scotty79 3y agoWhat if this macro could be expanded into valid typescript by preprocessor that runs before typescript compiler?
- armchairhacker 3y agoThat's an option, and maybe even the ideal one: an extension which takes a TypeScript+macros file and converts it into TypeScript before feeding to the TypeScript compiler. However, such a preprocessor will basically need to re-implement TypeScript's type checking. So either TypeScript must expose it via an API, or the preprocessor needs to itself implement a subset (which as mentioned, could also be faster)
- 3y ago
- paxys 3y ago> Typescript would become some kind of runtime on top of JavaScript. A new language that compiles to JavaScript. Typescript isn't a runtime on top of JavaScript, but it very much is "a new language that compiles to JavaScript".
- codeflo 3y agoYes, but it's special in that it compiles by erasure. (Mostly -- the cases where it doesn't are considered historical mistakes.)
- vanviegen 3y agoOk. And why is that important? So one could meticulously add typing to your JavaScript application, and then strip it all out with a regex in order to deploy? What real-life benefit does 'compile by erasure' offer?
- codeflo 3y agoThat's essentially what all the fast transpilers do -- esbuild, babel etc. They don't typecheck the code at all, they just parse it and strip out the type annotations. This means that you can run and test code that doesn't typecheck yet -- very useful during development. Also, production builds can run the typechecker in parallel with other build steps. That's how we optimized our build system at work. But essentially, it's a design choice by the TypeScript team. They've decided that TypeScript shouldn't add runtime features on top of JavaScript, but instead should simply type JavaScript, and I think this has contributed to the success of TypeScript.
- johnfn 3y agoI think the point is that TypeScript isn't really "a new language". It's an existing language with an additional feature. The fact that TS maintains the promise that types can be stripped means that TS is upholding a contract that it will not stray from Javascript. It can't, for example, add new language features.
- twelve40 3y ago> dynamically typed language, and that's also nice what is nice about a dynamically typed language? like, seriously, can you list some reasons for a dynamically typed language to exist?
- andix 3y agoTypes can get complicated. To an extent that code gets extremely overcomplicated by using a typed language. Typed languages encourage to use many layers of DTOs and models. With dynamic languages you can just code, without being held back by a OOP type system, but it can get very complicated to understand what the typed of you parameters and return values actually are. Typescript gives you the best of both worlds.
- Barrin92 3y agoPeter Norvig summed it up in one of his presentations https://norvig.com/design-patterns/design-patterns.pdf https://norvig.com/design-patterns/design-patterns.pdf "Dynamic Languages have fewer language limitations Less need for bookkeeping objects and classes Less need to get around class-restricted design. Study of the Design Patterns book: 16 of 23 patterns have qualitatively simpler implementation in Lisp or Dylan than in C++ for at least some uses of each pattern[...]"
- vbezhenar 3y agoTypeScript is not JavaScript with type annotations. One of the modes, may be. TypeScript supports emitting old JS constructions which look nothing like original typescript code. So it's more like type annotations + babel. Adding one more thing to this set. Extremely useful thing. I think it's a good idea. I miss it. It's crazy that I can't JSON.parse string into typed structure safely. Every other language can do that.
- mrloba 3y agoYou can easily parse json into types using something like typebox. Not only does this work, it works much better than many other languages. Have fun trying to represent even a simple patch request, or discriminated union, in something like c#
- andix 3y agoNo, this is not crazy, this is the design goal of TypeScript. If you want a statically and runtime typed language in the browser, you should not use typescript. Use Kotlin, Rescript, …
- adjav 3y agoMy understanding has long been that web developers have decided to turn Javascript into C#, one proposal at a time.