Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

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.



I'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.


I think TypeScript loosely mapping to JS is important if just because JS sourcemaps suck, like they're so often randomly ignored in callstacks etc. And JS semantics are so subtle it makes transpiling any other language a pain.

But this doesn't justify removing every codegen feature. Namespaces and enums won't make your code less reasonable, and moreover they're just syntax sugar, they don't change actual JS semantics.


I 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.


Enums 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.


Trouble 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).


I 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.


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

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.


Typescript 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.


This 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.


I 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...


What 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".


In 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?


I agree with you. They both serve a purpose and should be used when they make the most sense.


The Java crowd indeed gave us god awful classes.

But before that there were countless competing models for creating objects or object factories.

Obviously, JavaScript is an object oriented language, too. You cannot escape that fact if you are determined to make the browser paint anything.

Classes effectively solved the "How?"

To pretend you don't need object orientation in JavaScript is really trying hard to make JavaScript into an entirely different language.


> But before that there were countless competing models for creating objects or object factories.

Java and C# had object factories even though in those languages classes could not be avoided. People wanted classes because they could not figure how to program without them.

> To pretend…

Don’t use this or new in your code and suddenly a tremendous amount of your code is exposed as unnecessary superfluous vanity. That isn’t making the language into something else.


> Java and C# had object factories

Object factories were competing models (plural) for creating any object. A total replacement for classes and the like, not an augmentation.

Here's one such model:

  function createCar(spec) {
    const {speed} = spec;
  
    let position = 0;
  
    return Object.freeze({
      move() {
       position += speed;
      },
      get position() {
        return position;
      }
    });
  }
And so you'd find this or any other model or multiple competing models in the very same code base.

It sucked.

> Don’t use this or new in your code

You are going to be mutating the internal state of objects. Using this and new or not.


I always thought it was because of ActionScript 3


You mean ES4, the revenge ;)

Proxies and classes were definitely salvaged from ES4/ActionScript/Jscript.net.

We wouldn't be needing Typescript, had ES4 been adopted (ironically Microsoft was against it, because Silverlight...).

Someone definitely needs to write a book about the whole saga.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: