This is a follow up of this question.
What I am trying to achive is: passing multiple sub-classes to a function is there a way to return an object that as a "schema" with the types of sub-classes passed? So that i can preserve all intellisense features.
Below my failed attempt.
class Component {
get name(): string {
return this.constructor.name
}
}
class Direction extends Component {
x: number
y: number
constructor(x: number = 0, y: number = 0) {
super()
this.x = x
this.y = y
}
}
class Rectangle extends Component {
x: number
y: number
w: number
h: number
constructor(x: number, y: number, w: number, h: number) {
super()
this.x = x
this.y = y
this.w = w
this.h = h
}
}
class Entity {
components: Map<string, Component>
constructor(...components: Component[]) {
this.components = new Map()
components.forEach(component => this.add(component))
}
get<C extends Component[]> (...components: { [P in keyof C]: new (...args: any[]) => C[P] }): Record<string, Component> {
return components.reduce(
(accumulator, component) => {
accumulator[component.name.toLocaleLowerCase()] =
this.components.get(component.name)!
return accumulator
},
{} as Record<string, Component>
)
}
add(component: Component) {
this.components.set(component.name, component)
}
}
const player = new Entity(
new Rectangle(100, 100, 100, 100),
new Direction(1, 1)
)
const p_components = player.get(Rectangle, Direction)
console.log(p_components.rectangle)
// Intellisense doens't know p_components properties
// Intellisense infers p_components.rectangle as Components - It should be Rectangle instead
I've also searched the web and the closest to this I've found is this. But I don't know how I can implement it in my code and if it helps.