Typescript infer constructor parameter from array of classes

Viewed 41

I have an array of classes, from which I'd like to init one class based on a static method (getSlug).

interface AnimalParams {
  name: string;
  color: string;
}

class Animal {
  params: AnimalParams;
  constructor(params: AnimalParams) {
    this.params = params;
  }
}

interface DogParams extends AnimalParams {
  species: string;
}

class Dog extends Animal {
  params: DogParams;
  constructor(params: DogParams) {
    super(params);
    this.params = params;
  }

  static slug(): string {
    return "dog";
  }
}

interface CatParams extends AnimalParams {
  sound: "meow";
}

class Cat extends Animal {
  params: CatParams;
  constructor(params: CatParams) {
    super(params);
    this.params = params;
  }

  static slug(): string {
    return "cat";
  }
}

const arr = [Dog, Cat];

const animal = arr.find((x) => x.slug() === "dog");
if (!animal) {
  throw new Error("not found");
}
// union params type
// Property 'sound' is missing in type '{ name: string; color: string; species: string; }' but required in type 'CatParams'.

// new (params: DogParams & CatParams)
const a = new animal({
  name: "doggy",
  color: "black",
  species: "bulldog"
});

https://codesandbox.io/s/bold-james-15fsmq?file=/src/index.ts

Now when I try to instantiate a class, constructor params become a union type of DogParams & CatParams, but it should be DogParams | CatParams.

How can I resolve this issue?

0 Answers
Related