问题
In C++ there is something called a friend class. As far as I know, there's no such thing in TypeScript/JavaScript. Is there a way to simulate such behavior of friend class in TypeScript/JavaScript?
To give better context (if needed) of why and what I try to do, I make some small game for fun (and to learn stuff) and try to do this. At the moment I just use public methods and everything works, but I would like to limit accessibility of those methods to just one other class. I use TypeScript, if that helps.
回答1:
TypeScript only provides protected and private access modifiers. It does not currently have something like friend or internal.
To get similar effects: if you are packaging your code as a library and emitting .d.ts
declaration files for it, you can use the /** @internal */
JSDoc annotation on the properties you don't want outsiders to use, along with specifying the --stripInternal
compiler option. This will cause the exported declaration to leave out these properties.
Another way to do something similar is to come up with a public interface
which your class implements, and then only export the class as the public interface. For example:
// 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;
This is tedious but makes it very explicit which parts of your code are meant for outsiders and which are not.
Or, since neither of the above actually prevent people from accessing private/internal info in JavaScript at runtime, you could use an IIFE to really hide those things from outsiders. This might be more annoying to do in TypeScript, though, since it will probably require you to create the above public interfaces in order to typecheck propertly.
So there are some options for you. Hope they help. Good luck!
回答2:
Well, of course it's been proposed. See https://github.com/Microsoft/TypeScript/issues/2136.
But at the end of the day, TypeScript is not C++, and is not Java. Yes, TypeScript (and ES6) provide classes, which sort of look like classes in a classic OOP language, but the language is not really intended to be a full-fledged OOP language with all the OOP bells and whistles, nor should it be.
If you find yourself wanting friend classes, you should consider the possibility that you are over-engineering your class hierarchies and placing too much of your design logic into class structures, trying to make JS/TS into an OOP language it was never intended to be.
来源:https://stackoverflow.com/questions/45847399/friend-class-in-typescript