Issue
I’m trying to build a function that would take a class definition as a parameter in order to switch on it’s name
This is just to simplify my tests by creating one function that can generate data based on a given class
getMockDataForClass(c: Class, override){
if(c === Person){ return getPersonMockData(override)}
if(c === Dog){ return getDogMockData(override)}
...
}
so that I can write test like:
it('should process a persons information', ()=>{
const p = getMockDataForClass(Person)
...
})
it('should compare 2 persons', ()=>{
const p = getMockDataForClass(Person)
const p2 = getMockDataForClass(Person, {name: 'Jane'})
})
However there doesn’t seem to be a type of class
which would allow me to make this generic
Solution
Do you just want a "newable" type here?
type Class = {
new (...args: unknown[]): unknown
name: string // if you need it
}
Which works as you may expect:
class Person { person = true }
class Dog { dog = true }
function getMockDataForClass(c: Class, override: Class){
if(c === Person) { return override}
if(c === Dog){ return override }
return c
}
getMockDataForClass(Person, Dog)
If you want the second argument to be an instance of the class that is the first argument, then you need to capture the class constructor as a generic parameter. And then the override
is an instance of that class.
For instance:
type Class = {
new (...args: any[]): unknown
}
class Person {
constructor(public name: string) {}
}
class Dog {
constructor(public breed: string) {}
}
function getMockDataForClass<T extends Class>(c: T, override: InstanceType<T>){
//implementation...
}
getMockDataForClass(Person, {name: 'John'}) // fine
getMockDataForClass(Dog, {breed: 'Terrier'}) // fine
getMockDataForClass(Person, {breed: 'Terrier'}) // error
Answered By – Alex Wayne
Answer Checked By – Marilyn (BugsFixing Volunteer)