【TypeScript】クラスのプロパティにつけるprivateとreadonlyの違い

`private`修飾子を付けたプロパティはクラス内からのみ参照できる
`readonly`修飾子を付けたプロパティは読み込み専用になる

...🤔?

読んでもわからなかったので、調査してみました。

#### `private`修飾子を付けたプロパティは

 - クラス内で値を呼び出し可能 <br>
   `this.プロパティ名`
 - クラス内で値を書き換え可能 <br>
   `this.プロパティ名 = 新しい値`
 - ゲッターで値を呼び出し可能 <br>
   `インスタンス名.ゲッター名`
 - セッターで値を書き換え可能 <br>
  `インスタンス名.セッター名 = セッターに渡す引数`
 - サブクラス内で値を呼び出し不可 <br>
   `this.プロパティ名` ←Error
 - サブクラス内で値を書き換え不可 <br>
   `this.プロパティ名 = 新しい値` ←Error
 - サブクラスのインスタンスでメインクラスから継承したゲッターを使って値を呼び出し可能 <br>
   `サブクラスのインスタンス名.メインクラスのゲッター名`
 - サブクラスのインスタンスでメインクラスから継承したセッターを使って値を呼び出し可能 <br>
   ``サブクラスのインスタンス名.メインクラスのセッター名 = セッターに渡す引数`

#### `readonly`修飾子を付けたプロパティは

 - クラス内で値を呼び出し可能<br>
   `this.プロパティ名`
 - クラス内で値を書き換え不可<br>
   `this.プロパティ名 = 新しい値` ←Error
 - ゲッターで値を呼び出し可能 <br>
   `インスタンス名.ゲッター名`
 - セッターで値を書き換え不可 <br>
   `インスタンス名.セッター名 = セッターに渡す引数` ←Error <br>
   そもそもセッター内で`this.プロパティ名 = 新しい値` ←Error
 - サブクラスで値を呼び出し可能 <br>
   `this.プロパティ名`
 - サブクラスで値を書き換え不可 <br>
   `this.プロパティ名 = 新しい値` ←Error
 - サブクラスのインスタンスでメインクラスから継承したゲッターを使って値を呼び出し可能 <br>
   `サブクラスのインスタンス名.メインクラスのゲッター名`
 - サブクラスのインスタンスでメインクラスから継承したセッターを使って値を呼び出し不可 <br>
   そもそもメインクラスのセッター内で`this.プロパティ名 = 新しい値` ←Error

#### 参考(試行錯誤の跡地)

コメントとかおかしなところがあるかもしれませんが。

```ts

class Hito {
  name: string;
  private _age: number;

  constructor(name: string, _age: number) {
    this.name = name;
    this._age = _age;
  }

  get age() {
    return `_age: ${this._age}`
  }

  set changeAge(age: number) {
    this._age = age;
  }

  debug() {
    return `_age: ${this._age}`;
  }
}

const me = new Hito('Taro', 30);

console.log(me.name) // Taro

// console.log(me._age)
// Error Property '_age' is private and only accessible within class 'Hito'.
// Error プロパティ '_age' はプライベートで、クラス 'Hito' 内でのみアクセスできます。

// me._age = 20;
// Error Property '_age' is private and only accessible within class 'Hito'.
// Error プロパティ '_age' はプライベートで、クラス 'Hito' 内でのみアクセスできます。

console.log(me.debug()); // _age: 30
console.log(me.age); // _age: 30
me.changeAge = 20;
console.log(me.debug()); // _age: 30
console.log(me.age); // _age: 30

class Hito2 {
  name: string;
  readonly _age: number;

  constructor(name: string, _age: number) {
    this.name = name;
    this._age = _age;
  }

  get age() {
    return `_age: ${this._age}`
  }

  set changeAge(age: number) {
    this._age = age;
    // Error Cannot assign to '_age' because it is a read-only property.
    // Error 読み取り専用プロパティであるため、'_age' に代入することはできません。
  }

  debug() {
    return `_age: ${this._age}`;
  }
}

console.log(`=====`)


const me2 = new Hito2('Taro', 30);

console.log(me2.name) // taro

// console.log(me._age)
// Error Property '_age' is private and only accessible within class 'Hito'.
// Error プロパティ '_age' はプライベートで、クラス 'Hito' 内でのみアクセスできます。

// me._age = 20;
// Error Property '_age' is private and only accessible within class 'Hito'.
// Error プロパティ '_age' はプライベートで、クラス 'Hito' 内でのみアクセスできます。

console.log(me2.debug()); // _age 30
console.log(me2.age); // _age 30
me2.changeAge = 20;
console.log(me2.debug()); // _age 30
console.log(me2.age); // _age 30

console.log(`=====`)

class NewHito extends Hito{
  constructor(name: string, _age: number) {
    super(name, _age)
  }
  debug2() {
    return `${this._age}`
    // Error プロパティ '_age' はプライベートで、クラス 'Hito' 内でのみアクセスできます。
  }
}

const me3 = new NewHito('Momoko', 42);

console.log(me3._age)
// Error プロパティ '_age' はプライベートで、クラス 'Hito' 内でのみアクセスできます
me3._age = 80
// Error プロパティ '_age' はプライベートで、クラス 'Hito' 内でのみアクセスできます。
console.log(me3.debug2()); // _age 42
console.log(me3.age); // _age 42
me3.changeAge = 20;
console.log(me3.debug()); // _age 20
console.log(me3.age); // _age 20

console.log(`=====`)

class NewHito2 extends Hito2{
  constructor(name: string, _age: number) {
    super(name, _age)
  }
  debug2() {
    return `${this._age}`
  }
}

const me4 = new NewHito2('Momoko', 42);

console.log(me4._age) // 42
// me4._age = 80
// 読み取り専用プロパティであるため、'_age' に代入することはできません。
console.log(me4.debug()); // _age 42
console.log(me4.age); // _age 42
me4.changeAge = 20;
console.log(me4.debug()); // _age 20
console.log(me4.age); // _age 20
```