Basically, I'm trying to type getA() in the following (drastically simplified) code:
interface Base {
readonly id: string
}
class Foo implements Base {
get id() {return 'a foo'}
get ping() {return 'pong'}
}
abstract class Bee {
abstract get bing(): string
}
class Bar implements Base, Bee {
get id() {return 'a bar'}
get bing() {return 'Crosby'}
}
class Baz implements Base, Bee {
get id() {return 'a bar'}
get bing() {return 'cherry'}
}
function getA(type, name) {
// Some dynamic lookup happens here
if (type === Foo) {
return new Foo()
} else if (type === Bee && name === 'bar') {
return new Bar()
} else if (type === Bee && name === 'baz') {
return new Baz()
} else {
throw new Error('unknown args')
}
}
console.log(getA(Foo, 'foo').ping)
console.log(getA(Bee, 'bar').bing)
This is doable (though awkward) without the abstract classes:
function getA<T extends Base>(type: {new(): T}, name: string): T
but abstract classes don’t have constructors (for obvious reasons) and I can’t seem to find any other way to refer to the type (rather than an instance of it). I’m also open to suggestions of possible refactors if there might be a better way of doing this.