在TypeScript中不再可能将数据类型映射到函数参数?

时间:2019-08-19 18:14:59

标签: typescript

我在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}
    })

0 个答案:

没有答案