Skip to content

Conversation

Andarist
Copy link
Owner

No description provided.


The `this` keyword refers to the instance of the class, and it's used to access the properties and methods of the class.

Now, when we create a new instance of the `Album` class, we can pass an object with the properties we want to set. If we don't provide any values, the default values will be used:
Copy link
Owner Author

@Andarist Andarist Jul 14, 2024

Choose a reason for hiding this comment

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

you mention default values here and u even rely on them in the latter example but u have no default values here anywhere - u only introduce them later which is pretty confusing at this moment of reading

// Output: 69 Love Songs by The Magnetic Fields, released in 1999.
```

While using a class as a type is possible, it's a much more common pattern to require classes to implement a specific interface.
Copy link
Owner Author

Choose a reason for hiding this comment

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

this feels pretty opinionated, in many codebases I've seen classes were used as types directly - if you don't share an interface between multiple classes then why would I bother redeclaring every property/method to get that interface?


### `readonly` Class Properties

As we've seen with types and interfaces, the `readonly` keyword can be used to make a property immutable. This means that once the property is set, it cannot be changed:
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
As we've seen with types and interfaces, the `readonly` keyword can be used to make a property immutable. This means that once the property is set, it cannot be changed:
As we've seen with types and interfaces, the `readonly` keyword can also be used with class properties. This means that once the property is set, it cannot be changed:


### `public` and `private` properties

The `public` and `private` keywords are used to control the visibility and accessibility of class properties.
Copy link
Owner Author

Choose a reason for hiding this comment

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

calling out both visibility and accessibility here calls out for defining both (or at least for differentiating between both). It's kinda the same thing here so I think I'd avoid using both terms and stick to one


Next, we need to add a constructor that includes all of the properties from the `Album` class as well as the `bonusTracks` property. There are a couple of important things to note about the constructor when extending a class.

First, the arguments to the constructor should match the shape used in the parent class. In this case, that's an `opts` object with the properties of the `Album` class along with the new `bonusTracks` property.
Copy link
Owner Author

Choose a reason for hiding this comment

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

There is no such requirement, I wouldn't recommend deviating too far but this is perfectly valid code for TS:

class Base1 {
  constructor(arg: number) {}
}
class Cls1 extends Base1 {
  constructor(arg: string) {
    super(parseInt(arg));
  }
}

class Base2 {
  constructor(arg: { foo: string }) {}
}
class Cls2 extends Base2 {
  constructor(arg: { bar: string }) {
    super({ foo: arg.bar });
  }
}


### Exercise 2: Implementing Class Methods

In this exercise, we've simplified our `CanvasNode` class so that it no longer has read-only properties:
Copy link
Owner Author

Choose a reason for hiding this comment

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

read-only vs readonly spelling is not used consistently across the book

}
```

The `#` in front of the `x` and `y` properties means they are `readonly` and can't be modified directly outside of the class. In addition, when a getter is present without a setter, its property will also be treated as `readonly`, as seen in this test case:
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
The `#` in front of the `x` and `y` properties means they are `readonly` and can't be modified directly outside of the class. In addition, when a getter is present without a setter, its property will also be treated as `readonly`, as seen in this test case:
The `#` in front of the `x` and `y` properties means they are private and can't be modified directly outside of the class. In addition, when a getter is present without a setter, its property will also be treated as `readonly`, as seen in this test case:

In general, something weird is going on here and in subsequent paragraphs. You mention readonly, and getters without setters but there are no getters here. There is a mismatch between text and the presented code.

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 know that getter was supposed to be introduced by the reader in the previous exercise but it's still confusing to me. You didn't even introduce getters and setters at all before, and now you softly expect the reader to be aware of them.

Those exercises are about classes but now you present a simple object type with a simple property as a validation for this statement:

In addition, when a getter is present without a setter, its property will also be treated as readonly, as seen in this test case:

I don't feel like the example is related to this paragraph. That example has a readonly property because it has a readonly modifier on it - not because it's a getter-only property.

}
```

As discussed in a previous section, it's safer to use the arrow function to avoid issues with `this`.
Copy link
Owner Author

Choose a reason for hiding this comment

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

Safer but less memory-efficient:

class Test1 {
  method() {}
}

new Test1().method === new Test1().method; // true

class Test2 {
  method = () => {};
}

new Test2().method === new Test2().method; // false

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 feel like this chapter is missing:

  • typeof Cls vs Cls (the first one is the type of the class - the second one is the type of an instance of this class)
  • that TS is structural in nature and that, unlike many other languages, TS doesn't have nominal classes... unless u have private properties. I think this is a big gotchat for newcomers, especially for those coming from other backgrounds

You could also mention gotchas around bivariant methods here but you didn't get to related topics just yet so perhaps it's not the right time yet. Although methods bivariance is hugely motivated by classes

@Andarist Andarist marked this pull request as ready for review July 14, 2024 22:06
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