我在a project of mine中有此代码,但是我再也找不到在TypeScript中进行此转换的方法,每次尝试似乎都失败了:
// Define data containers with a factory function.
// Create a type with argument/return types, e.g.:
// ComponentId<[number], {amount: number}>
const friction = world.addComponent('friction', (amount: number) => ({amount}));
const velocity = world.addComponent('velocity', (vx: number, vy: number) => ({vx, vy}));
// Add a function that will run over the specified components. The storages
// for the components provided will be added as arguments to the function.
// Basically, turn a ComponentId list into a function signature:
// (world, entities, frictions: {get(…): {amount: number}}, …)
world.addSystem(
'friction',
[friction, velocity],
(world, entities, frictions, velocities) => {
const dt = world.globals.deltaTime;
for (const {id} of entities) {
const {amount} = frictions.get(id);
const velocity = velocities.get(id);
velocity.vx *= 1 - amount * dt;
velocity.vy *= 1 - amount * dt;
}
},
);
基本上在较旧的TypeScript版本(〜3.1左右)中是可行的(请参阅GitHub source code for how),但是现在我看不到如何将输入数组[friction, velocity]
映射到正确键入的参数中addSystem
中的function参数...
有人知道该怎么做吗?
编辑:这是类型的简化示例:
interface ComponentId<I, O> {}
function createComponent<I extends any[], O>(
factory: (...input: I) => O
): ComponentId<I, O> {
return "normally this would be an identifier for the component"
}
// Create a component, which now has underlying type:
// ComponentId<[number, number], {x: number, y: number}>
const positionComponent = createComponent((x: number, y: number) => ({x, y}))
// And another...
const velocityComponent = createComponent((vx: number, vy: number) => ({vx, vy}))
// This is where the magic should happen...
type TurnComponentIdListIntoArguments<???> = ???
// step(...) should be a function that receives the
// "O" type of every ComponentId as an argument.
function createSystem<C extends ???>(
components: C,
step: (...values: TurnComponentIdListIntoArguments<C>) => void
): void {
// This part doesn't matter...
}
const moveSystem = createSystem(
[positionComponent, velocityComponent],
(position, velocity) => {
// For simplicity's sake, let's say we'd expect position and velocity to be:
// {x: number, y: number} and {vx: number, vy: number}
})