web-dev-qa-db-ja.com

TypeScriptのFriendクラス

C++には、フレンドクラスと呼ばれるものがあります。私の知る限り、TypeScript/JavaScriptにはそのようなものはありません。 TypeScript/JavaScriptでそのようなフレンドクラスの動作をシミュレートする方法はありますか?

理由と私がやろうとしていることの(必要に応じて)より良いコンテキストを提供するために、私は楽しみのために(そして何かを学ぶために)小さなゲームを作り、 this を試します。現時点では、パブリックメソッドを使用するだけですべてが機能しますが、これらのメソッドのアクセシビリティを他の1つのクラスだけに制限したいと思います。それが役立つ場合は、TypeScriptを使用します。

14
kamyl

TypeScriptは protectedおよびprivate アクセス修飾子のみを提供します。現在 friend または internal のようなものはありません。


同様の効果を得るには、コードをライブラリとしてパッケージ化し、そのために.d.ts宣言ファイルを発行する場合は、外部に使用させたくないプロパティに/** @internal */ JSDocアノテーションを使用できます。 --stripInternalコンパイラオプション を指定します。これにより、エクスポートされた宣言でこれらのプロパティが省略されます。


同様のことを行う別の方法は、クラスが実装するパブリックinterfaceを考え出し、そのクラスをパブリックインターフェースとしてのみエクスポートすることです。例えば:

// public interfaces
export interface UnitStatic {
  new(grid: Grid, x: number, y: number): Unit;
}
export interface Unit {
  move(x: number, y: number): void;
}
export interface GridStatic {
  new(): Grid;
  NUM_CELLS: number;
  CELL_SIZE: number; 
}
export interface Grid {
  // public methods on Grid
}

// private implementations
class UnitImpl implements Unit {
  constructor(private grid: GridImpl, private x: number, private y: number) {

  }
  move(x: number, y: number) {
    // ...
  }
}

class GridImpl implements Grid {
  cells: Unit[][] = [];
  constructor() {
    // ...
  }
  static NUM_CELLS = 10;
  static CELL_SIZE = 20;
}

//public exports
export const Unit: UnitStatic = UnitImpl;
export const Grid: GridStatic = GridImpl;

これは退屈な作業ですが、コードのどの部分が部外者向けであり、どの部分がそうでないかを非常に明確にします。


または、上記のどちらも実行時にJavaScriptのプライベート/内部情報へのアクセスを実際に妨げないため、 [〜#〜] iife [〜#〜] toreallyそれらを部外者から隠します。ただし、適切に型チェックするために上記のパブリックインターフェイスを作成する必要があるため、TypeScriptでこれを行うのはより面倒です。


したがって、いくつかのオプションがあります。彼らが助けてくれることを願っています。幸運を!

16
jcalz