8 ms·
tldr: avoid features in TypeScript which must emit runtime code when compiling to JavaScript - that is, any TypeScript-exclusive feature that’s not type annotat
by armchairhacker 5y ago
tldr: avoid features in TypeScript which must emit runtime code when compiling to JavaScript - that is, any TypeScript-exclusive feature that’s not type annotations.
Honestly most of these features are really useful, and as someone who never wants to work in raw JavaScript, I wish they were just added to JavaScript instead. Why shouldn’t JavaScript have enums, namespaces, private modifiers which aren’t #, and decorators? JS already gets new features which break backward-compatibility, mine as well add features which fix compatibility with TypeScript.
- throw_m239339 5y agoI completely disagree with that article. Instead of "avoid this or that", one should be understanding how Typescript compiler works and not treat it as a blackbox. Ultimately, Typescript does compile to Javascript. One cannot use Typescript without understanding Javascript, since every single Javascript library is not written in Typescript.
- withinboredom 5y agoOne should also understand the machine code that a traditional language compiles to and how the CPU executes it. Ultimately, your language compiles to machine code. /s No one should need or worry about what an abstraction compiles to unless they’re specifically working on that abstraction or there’s a language bug.
- throw_m239339 5y agoTypescript compiler is first and foremost a type system for Javascript. It's not an independent language. In fact it broke backward compatibility many times to follow the ES spec. > One should also understand the machine code that a traditional language compiles to and how the CPU executes it. Ultimately, your language compiles to machine code. /s If libraries you use are all written in machine code, then sure, you should have an understanding of machine code. Your comparison clearly doesn't work here. > No one should need or worry about what an abstraction compiles to unless they’re specifically working on that abstraction or there’s a language bug. When an abstraction is that leaky, it's barely an abstraction. Typescript does force you to choose a Javascript version as a compilation target. Obviously you are forced to know what Javascript version supports what feature because Typescript isn't going to polyfill every missing feature depending on your Ecmascript target.
- austincheney 5y agoThis is how ES6 got classes. Developers wanted JS to be some other language they favored more. In that case specifically people were really hoping to make the language look and feel like Java, probably because they were trained in Java and couldn’t figure out functions as first class citizens.
- throw_m239339 5y agoI think class were needed because too many developers were creating their own (incompatible) class systems on top of prototypal inheritance (which is more verbose). The problem with Typescript is that too many Typescript developers don't understand Javascript itself, which is an completely different issue. That and the obsession for some to reproduce JEE everywhere including in the browser...
- moystard 5y agoWhat do you mean by reproducing JEE? Leveraging OOP in your Javascript programs? I really dislike this tendency of certain Javascript developers to qualify combining OOP with Javascript as "not understanding the language".
- tentacleuno 5y agoIn my humble opinion, they're both fine. Use functions where you need to, and do the same with classes. They're both citizens of the language, so why not utilize them?
- moystard 5y agoI agree with you. They both serve a purpose and should be used when they make the most sense.
- wdb 5y agoI always thought it was because of ActionScript 3
- cromwellian 5y agoI'd go further. There's no strong argument for why code-gen is bad. Why is a compilation process that is simply "remove type annotations" inherently better than one that emits code, or does code transformations, other than just personal preference, aesthetics, or simplicity? About the only positive that is qualitatively different is the simplicity of comparing the output to the input. But for someone building a large typescript codebase, and who uses sourcemaps, it's not really a big issue. There are many many languages that compile-to-JS, and I feel that insisting on 'purity' for purity's sake isn't really a good justification. That, TS as a super-set of JS instead of as a isomorphic mapping between constructs is a perfectly viable way to innovate in the language space.
- tuyiown 5y agoI see the next to zero codegen in typescript as a strategy: it removes all discutions about languages features besides typing, guarantees next to zero issues in production in case of code generation bug, making compiler deliveries safe and avoid need of coordination in toolchain.
- cromwellian 5y agoEnums and namespaces are hardly complex code gen or generate 'issues'. People would often manually namespace in JS a few years ago, and namespaces and enums can really just be seen a lightweight holder object instances. Indeed, enums in Java are class instances. Besides, there is an straightforward way to remove enums from a program just like removing type annotations: Inline them as static fields of an object. There is a simple syntactic transformation. e.g. change 'enum' to 'const', add a '=' before the '{' and use ':' instead of '=' const HttpMethod = { Get: 'GET', Post: 'POST' }; // now this no longer breaks const method = HttpMethod.Post; Namespaces can be translated in almost the exactly same way.
- chrismorgan 5y agoTrouble with your const there as written is that you don’t have a type that’s equal to "GET" | "POST". Fortunately, this can be done without repetition or too much bother: const HttpMethod = { Get: 'GET', Post: 'POST', } as const; type HttpMethod = (typeof HttpMethod)[keyof typeof HttpMethod]; Maybe wrap the `{…} as const` in Object.freeze(…) for good measure. It’d be really nice if they’d improve the ergonomics on this in some way (`type Values<T> = T[keyof T]` would reduce it to `type HttpMethod = Values<typeof HttpMethod>`, which is a start but not enough), to make it a genuine and suitable alternative to enum (minus the other frippery that’s generated) and const enum (because it’s pure JavaScript, not an extension).