I have an array of classes, from which I'd like to init one class based on a static method (getSlug), and pair it with it correspondent consturctor param.
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 args = {
dog: DogParams,
cat: CatParams
}
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(args[animal.slug()]);
https://codesandbox.io/s/bold-james-15fsmq?file=/src/index.ts
Now when I try to instantiate a class, constructor params become unexpectedly an intersection of DogParams & CatParams
, but it should be DogParams | CatParams
union. slug
will be known at runtime only. My main goal is to map constructor instances to their constructorParam types.
How can I fix the types?