typescript 是否可以在动态数组中获取类型

pkln4tw6  于 2023-03-19  发布在  TypeScript
关注(0)|答案(1)|浏览(132)

我有下面的代码,在这里我可以向数组中添加任何内容。有没有可能在construct的匿名函数中获得正确类型的参数?
sandbox

const wrapper = <T>() => {
  const arr: T[] = [];

  const construct = (func: (...arr: T[]) => void) => {
    func(...arr);
  };
  const add = (x: T) => {
    arr.push(x);

    return { add, construct };
  };

  return { add };
};

const w = wrapper();

w.add(1)
  .add("2")
  .add({ a: 1 })
  .construct(
    // i need these to be correctly typed based on the types in add above  
    (a, b, c) => {
    //do something
  });

到目前为止,我只是尝试使用泛型类型,但似乎不能正常工作。

kgqe7b3p

kgqe7b3p1#

我想这能帮你解决90%的问题:

function wrapper<T extends any[]>(x: [...T]) {
  return {
    add<T2>(y: T2) {
      return wrapper([ ...x, y ])
    },
    run(f: (...x: T) => void) {
      f(...x);
    }
  };
}

const w = wrapper([]);

w
  .add(1)
  .add("2")
  .add({ a: 1 })
  .run(
    (a, b, c) => { }
  );
  • wrapper现在接受任何类似数组的参数(T extends any[]),并将其扩展为元组([...T]
  • add将该元组与T2的任何新值组合在一起,创建一个新的 Package 器,其中T现在引用[ ...T, T2 ]
  • run(或示例中的construct)需要签名为(...x: T)的函数,这意味着当前元组类型分布在各个参数上。

如果你在TypeScript中运行它,你可以看到(a, b, c) => void函数的正确签名:

我遇到的唯一问题是允许wrapper在没有任何参数的情况下被构造,我想你可以改变 Package 器,使其不带参数,然后为任何后续调用提供一个内部_wrapper,但这里可能有一个更好的方法。

相关问题