我在打字稿打字方面有问题。
[目前,我正在研究使用实体组件系统模型的小型游戏引擎。我想将接口类型“序列化”到类数组(每个接口属性的一种)中,以通知系统所需的组件。
我想理想地实现的目标:
export interface IMovable {
position: CompPosition;
velocity: CompVelocity;
}
export class MoveSystem extends System<IMovable> {
// This array should have type, to ensure all components classes from IMovable are listed.
protected requiredComponents = [ CompPosition, CompVelocity ];
/// ...
}
至少我想做什么:
export interface IMovable {
position: CompPosition;
velocity: CompVelocity;
}
export class MoveSystem extends System<IMovable> {
/* The properties of requiredComponents have the same name as in interface, but their types are
different - in interface, the type requires instances (which I want to keep this way in the
interface), but requiredComponents should contain classes. */
protected requiredComponents = {
position: CompPosition,
velocity: CompVelocity
};
/// ...
}
感谢每个建议。
所以这是我能想到的最好的。我不认为使用数组方法可以做到这一点(如果从开发人员的角度出发,如果不是人体工程学的话),所以我已经选择了对象一。
class Position implements Component {
x: number = 0
y: number = 0
readonly requiredComponents: {}
}
class Velocity implements Component {
velX: number = 0
velY: number = 0
readonly requiredComponents: {}
}
type ComponentConstructor<T> = new(...args: any[]) => T
interface Component<A = {}, B = {}, C = {}, D = {}> {
readonly requiredComponents: A & B & C & D
}
interface IMovable {
position: ComponentConstructor<Position>
velocity: ComponentConstructor<Velocity>
}
class Player implements Component<IMovable> {
readonly requiredComponents = {
position: Position,
velocity: Velocity,
}
}
关于这些组件如何工作/交互的更多上下文,我觉得我可能可以提供更好的解决方案-我不相信您仍然想做些什么。
我终于找到了解决方案。可能不是最好的一种,但它的工作方式应为:
type Class<T> = new(...args: any[]) => T;
type ComponentStore<T> = { [P in keyof T]: Component };
type RequiredComponents<T extends ComponentStore<T>> = { [P in keyof T]: Class<T[P]> };
abstract class System<T extends ComponentStore<T>> {
protected abstract requiredComponents: RequiredComponents<T>;
// ...
}
interface IMovable {
position: CompPosition;
velocity: CompVelocity;
}
class MoveSystem extends System<IMovable> {
protected requiredComponents = {
position: CompPosition,
velocity: CompVelocity
};
// ...
}
但是感谢所有尝试甚至阅读过的人。