Skip to content

Chapter 9 #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: initial
Choose a base branch
from
Open

Chapter 9 #9

wants to merge 1 commit into from

Conversation

Andarist
Copy link
Owner

No description provided.


Compared to handling the assignment manually, this saves a lot of code and keeps the class definition concise.

But unlike other TypeScript features, the outputted JavaScript is not a direct representation of the TypeScript code. This can make it difficult to understand what's happening if you're not familiar with the feature.
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can also introduce (at least at the moment) some unexpected issues in your code. You have mentioned before that class properties are initialized before the constructor gets executed. This is a fair approximation. So what about those properties? We could say the same about them - they are initialized at the beginning of the constructor. So which one runs first? Well, take a look at this:

// input
class Foo {
  prop = "foo";
  constructor(public foo: string = this.prop) {}
}

// output
"use strict";
class Foo {
    constructor(foo = this.prop) {
        this.foo = foo;
        this.prop = "foo";
    }
}

Oops, not cool 😉


But the fact that they're not consistent with numeric enums can be a source of confusion.

In fact, string enums are unique in TypeScript because they're compared _nominally_. All other types in TypeScript are compared _structurally_, meaning that two types are considered the same if they have the same structure. But string enums are compared based on their name (nominally), not their structure.
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
In fact, string enums are unique in TypeScript because they're compared _nominally_. All other types in TypeScript are compared _structurally_, meaning that two types are considered the same if they have the same structure. But string enums are compared based on their name (nominally), not their structure.
In fact, string enums are unique in TypeScript because they're compared _nominally_. Most other types in TypeScript are compared _structurally_, meaning that two types are considered the same if they have the same structure. But string enums are compared based on their name (nominally), not their structure.

logStatus(AlbumStatus2.NewRelease);
```

For those of us used to structural typing, this can be a bit of a surprise. But to developers used to enums in other languages, string enums will feel the most natural.
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The callout is good but it feels like the first time structural typing and nominal typing were called out here so I wouldn't be surprised if the reader just wouldn't know what you are talking about in this section

let albumStatuses = ["NEW_RELEASE", "ON_SALE", "STAFF_PICK"];
```

`const` enums do have some limitations, especially when declared in declaration files (which we'll cover later). The TypeScript team actually recommends avoiding `const` enums in your library code because they can behave unpredictably for consumers of your library.
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it might be worth calling out that one of the major limitations is that only TS can emit code using them, some other tools might have partial support too (IIRC esbuild handles them - at least to some extent, I'm not sure) but they are not guaranteed to work if using other tools. But maybe that goes outside of the scope of this book, dunno

logStatus(3);
```

This is different from string enums, which only allow the enum members to be used as types:
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it might be nice to call out that the reverse can be done:

enum MyEnum {
    foo = 'FOO',
    bar = 'BAR'
}

const test1: MyEnum.foo = 'FOO' // error
const test2: "FOO" = MyEnum.foo // ok

String enums are kind of subtypes of their string literal counterparts.

}
}

const madvillainy: RecordStoreUtils.Album = {
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i respect this example

```

This information will become crucial later when we look at the namespace's key use case: globally scoped types.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess you could document this pattern too:

function test(opts: test.Options) {
  opts.foo;
}
namespace test {
  export type Options = {
    foo: string;
  };
}

what is nice about it that there is no added runtime to this, it's just a function with some types collocated to it

@Andarist Andarist marked this pull request as ready for review July 15, 2024 11:28

The way string enums behave feels more natural - it matches how enums work in other languages like C# and Java.

But the fact that they're not consistent with numeric enums can be a source of confusion.
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant