打字稿:将接口类型序列化为 类 的数组
Typescript: Serialize interface types to array of classes
我在打字稿输入方面遇到问题。
目前,我正在研究使用实体-组件-系统模型的小型游戏引擎。我想将 "serialize" 类型的接口放入 类 的数组(每个接口的类型 属性)以通知系统所需的组件。
我想达到的理想状态:
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
};
// ...
}
但感谢所有尝试过甚至阅读过它的人。
我在打字稿输入方面遇到问题。
目前,我正在研究使用实体-组件-系统模型的小型游戏引擎。我想将 "serialize" 类型的接口放入 类 的数组(每个接口的类型 属性)以通知系统所需的组件。
我想达到的理想状态:
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
};
// ...
}
但感谢所有尝试过甚至阅读过它的人。