Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Friend class in TypeScript

Tags:

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.

like image 262
kamyl Avatar asked Aug 23 '17 18:08

kamyl


People also ask

What is the difference between friend and friend class?

It is a class that is used with 'friend' keyword. It is not necessary to declare it before using it. A friend class is used when a class is created as an inherited class from another base class. It is used to access private and protected members of the class.

What is a friend class in programming?

Friend Class A friend class can access private and protected members of other class in which it is declared as friend. It is sometimes useful to allow a particular class to access private members of other class.

What is a friend function of a class?

A friend function is a function that isn't a member of a class but has access to the class's private and protected members. Friend functions aren't considered class members; they're normal external functions that are given special access privileges.

What is the syntax of friend class?

Syntax of friend functions: class className{ // Other Declarations friend returnType functionName(arg list); }; As we can see above, the friend function should be declared inside the class whose private and protected members are to be accessed.


1 Answers

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!

like image 101
jcalz Avatar answered Sep 18 '22 23:09

jcalz