Live data from Hacker News

TypeScript Features to Avoid

executeprogram.com

161–170 of 212 posts

Re: TypeScript Features to Avoid

#161

Despite the large amount of criticism in the comments here I think that the point the article makes here is pretty valid. The described features are not what TypeScript itself wants to be, and I think if it wasn't for backwards compatibility the team would remove some of them. IIRC namespaces as well as the `import = ` syntax come from a time where ESM wasn't a thing yet but a module system was very much needed. So n…

> Enums IMO have no advantage over union types with string literals, e.g. `type Status = 'fulfilled' | 'pending' | 'failed'`.

Well I would say having to not repeat and update your code everywhere when you change or add a possible value is a pretty big advantage.

Re: TypeScript Features to Avoid

#162

Earlier quoted context omitted.

You can if you derive the union from a const array using indexed types. const MyTypeValues = ['a', 'b'] as const; type MyType = typeof MyTypeValues[number]; MyType is now a type 'a' | 'b'

This is the way, because iterating enums produces odd results due to a bidirectional mapping. I had always used enums in TS until this year, but union literals are better. I create my own enums with const objects, compute the type based off the object's values. So very similar this, just with an object as the source instead of an array.

Iterating over an enum in TypeScript always felt like code smell to me because of the filtering code I'd have to write to deal with the bidirectional mapping.

Re: TypeScript Features to Avoid

#163

This whole thing feels basically grounded in purity over practicality. In general it's a good idea to write idiomatic TypeScript. Even when I agree with the given recommendations, the given reasons don't seem like the strongest ones. I most strongly disagree with the recommendation against enums. Realistically, you will probably never run into a compiler bug from enum emit; maybe something like this might happen with…

> good idea to write idiomatic TypeScript

Is there really such a thing? Everyone seems to be writing TS with the "fake it until you make it" mantra, never quite reaching the "make it" phase. People still use "interface" and "type" interchangeably without rhyme or reason. Or "import" vs "import type". No one knows what they are doing in TS. Or why. Just look at this entire comment section.

Re: TypeScript Features to Avoid

#164

Despite the large amount of criticism in the comments here I think that the point the article makes here is pretty valid. The described features are not what TypeScript itself wants to be, and I think if it wasn't for backwards compatibility the team would remove some of them. IIRC namespaces as well as the `import = ` syntax come from a time where ESM wasn't a thing yet but a module system was very much needed. So n…

> Enums IMO have no advantage over union types with string literals, e.g. `type Status = 'fulfilled' | 'pending' | 'failed'`. Well I would say having to not repeat and update your code everywhere when you change or add a possible value is a pretty big advantage.

My IDE does this just fine (WebStorm, btw)

Re: TypeScript Features to Avoid

#165

Earlier quoted context omitted.

So... You have two declarations, one of which is a real array that's allocated at runtime. Is that really better than an enum? Not to mention, there's a slight mental overhead to parsing this. When I see this code, I might wonder if there's a reason for this to be an array. I might wonder if the order is intentional. An enum has a more clear intent. My only complaint is that enums are not string-by-default, so we end…

> Is that really better than an enum? Substantially. Look at the generated code for an enum. Also, this approach does not suffer the problems described by the article.

> Substantially. Look at the generated code for an enum.

I'll give you that. It looks like the TS compiler (according to the playground site) spits out some code that's intended for maximum compatibility with older versions of JS, even when targeting newer versions (which makes sense, since nothing is technically wrong about it).

It spits out:

    "use strict";
    var MyType;
    (function (MyType) {
        MyType["A"] = "a";
        MyType["B"] = "b";
    })(MyType || (MyType = {}));
when, we would obviously write the following in modern JS:

    "use strict";
    const MyType = {
        A: "a",
        B: "b",
    };
So that's a bit disappointing.

So, this could matter if you intend to actually read the emitted JS. If, however, you're TypeScript-only, this is more-or-less the same as reading the ASM spit out by your C compiler or the Java bytecode spit out by javac.

> Also, this approach does not suffer the problems described by the article.

This argument doesn't hold water, unless you're taking a philosophical stance. The argument is that most TypeScript features don't actually spit out JavaScript code and this one does.

But, if you're going to write an array that lists your variants (and then write code elsewhere to check if a string is contained by said array, etc), then "extra" JavaScript code is still being generated- it's just generated by you instead of the TypeScript compiler. Why should we care who generates the code?

This argument only works when we're comparing to writing a string literal union type and no other supporting code for that type. My comment was specifically addressing the case of writing an array to hold our literals instead of writing an enum, and I stand by my claim that an enum is better because it's the same runtime overhead, but more clearly communicates intent/semantics to your fellow TypeScript devs (including future-you).

Re: TypeScript Features to Avoid

#166

Despite the large amount of criticism in the comments here I think that the point the article makes here is pretty valid. The described features are not what TypeScript itself wants to be, and I think if it wasn't for backwards compatibility the team would remove some of them. IIRC namespaces as well as the `import = ` syntax come from a time where ESM wasn't a thing yet but a module system was very much needed. So n…

[deleted]

Re: TypeScript Features to Avoid

#167

Despite the large amount of criticism in the comments here I think that the point the article makes here is pretty valid. The described features are not what TypeScript itself wants to be, and I think if it wasn't for backwards compatibility the team would remove some of them. IIRC namespaces as well as the `import = ` syntax come from a time where ESM wasn't a thing yet but a module system was very much needed. So n…

Though I have never seen anyone till now call TypeORM a fine choice.

Re: TypeScript Features to Avoid

#168

Is anyone still using the class keyword in javascript or typescript? private field syntax doesn't matter in the first place if you don't use class {} anywhere ... I feel like most of the typescript code i've been in recently looked like it needed 0 more class declarations.

Try using Angular without using the "class" keyword.

(btw, don’t try using Angular at all if you are already happy with your career)

Re: TypeScript Features to Avoid

#169

Earlier quoted context omitted.

> Is that really better than an enum? Substantially. Look at the generated code for an enum. Also, this approach does not suffer the problems described by the article.

> Substantially. Look at the generated code for an enum. I'll give you that. It looks like the TS compiler (according to the playground site) spits out some code that's intended for maximum compatibility with older versions of JS, even when targeting newer versions (which makes sense, since nothing is technically wrong about it). It spits out: "use strict"; var MyType; (function (MyType) { MyType["A"] = "a"; MyType["…

> > Also, this approach does not suffer the problems described by the article. > > This argument doesn't hold water, unless you're taking a philosophical stance.

Respectfully, philosophy has nothing to do with this.

The argument that the other person made does, in fact, hold significant water. There are extremely long discussions about it on the Typescript GH repo.

.

> The argument is that most TypeScript features don't actually spit out JavaScript code and this one does.

No, it isn't.

.

> then "extra" JavaScript code is still being generated

I never said extra code was a problem. I have no problem with this.

What I said was that I found the code emitted by the enumeration stack to be problematic. You seem to have inferred cause (incorrectly.)

.

> Why should we care who generates the code?

Do you believe that I think a compiler should not generate code?

I never said anything of that form.

Genuinely, it's difficult to hold a discussion with people who read so deeply between the lines that they come to bizarre conclusions, then think those conclusions belong to the person on the other end of the wire.

.

> This argument only works when we're comparing to writing a string literal union type and no other supporting code for that type.

You're not talking about the same argument that I am.

.

> but more clearly communicates intent/semantics to your fellow TypeScript devs (including future-you).

I write documentation.

Re: TypeScript Features to Avoid

#170

Earlier quoted context omitted.

const enums are one of the few cases where type information changes the emitted JS, something that's arguably a bigger problem than TypeScript-specific, but still just syntax sugar, syntax highlighted in the article. Const enums are erased at compile time. If you have a reference to `MyEnum.VAR`, TS has to check whether the enum is a const enum, and if so, replace with something like `1 /* VAR */`. This means that th…

Thank you for the answer! I won't waste your time because I'm sure the answer is somewhere on the web, but off the top of my head, I don't understand why TS "has" to emit different JS. I would've assumed that the entire point of a const enum is to inline the raw value in the emitted JS, and thus, the programmer should be careful to remember/know that the code is dealing with raw ints/strings.

You potentially get a problem for every '.' expression. In this code:

  import {Something} from './file';
  console.log(Something.PROP);
TypeScript doesn't know what to emit without type information. If Something is a class, then the JS will look the same. But if it's a const enum, then TypeScript has to erase the Something.PROP expression and replace it with the constant value of that enum member, since Something will not exist at runtime.
Post reply on HN