Home > front end >  Restrict classes with same method names to be used interchangeably
Restrict classes with same method names to be used interchangeably

Time:12-07

Lets say we have Shape class like this:

export default class Shape {
  public render(): void {
    console.log("Render Shape");
  }
}

and Group class like this:

import Shape from "./Shape";

export default class Group {
  private shapes: Shape[] = [];

  public add(shape: Shape): void {
    this.shapes.push(shape);
  }

  public render(): void {
    for (const shape of this.shapes) {
      shape.render();
    }
  }
}

as you can see in Group class, we have method called add that accept 1 parameters with type Shape class. I want to pass only objects with type Shape to this method, but i can pass Group type as well.

import Group from "./Group";
import Shape from "./Shape";

const group1 = new Group();
group1.add(new Shape()); // this is ok

const group2 = new Group();
group2.add(group1); // this is ok in typescript view but i don't like it

Is there any solution to prevent this behaviour?

CodePudding user response:

I found a solution for this problem, but i like to know another solutions too.

import Shape from "./Shape";

type ValidateStructure<T, Struct> = T extends Struct
  ? Exclude<keyof T, keyof Struct> extends never
    ? T
    : never
  : never;

export default class Group {
  private shapes: Shape[] = [];

  public add<T>(shape: ValidateStructure<T, Shape>): void {
    this.shapes.push(shape);
  }

  public render(): void {
    for (const shape of this.shapes) {
      shape.render();
    }
  }
}

and now magic happens: enter image description here

  • Related