可以重用打字稿中的泛型类型吗?

时间:2020-07-08 19:54:17

标签: typescript typescript-generics

我想做类似的事情:

namepace Namespace<S,T,U,V> {
  type A = doSomething(S, T, U, V);
  type B<X> = doSomethingB(type<A>, V, X);

  interface I<X, Y> {
     a: A;
     b: B<X>
  }
}

基本上,我想重用通用参数,而不是每次都重复它们。我不想做类似的事情:

type A<S, T, U, V> = doSomething(S, T, U, V);
type B<S, T, U, V, X> = doSomething(A<S, T, U, V>, V, X);

interface I<S, T, U, V, X> {
  a: A<S, T, U, V>;
  b: A<S, T, U, V, X>;
}

另一种描述方式等效于C ++中的嵌套typedef

template <typename T>
class Abc<T> {
  template <typename U>
  typedef myType<U> = MyFunctor<T, U>;
}

// This works
Abc<T>::myType<U> x;

根据@jcalz,这是问题的独立示例。不能真正使它最小化,因为重点是要有很多类型。所有困扰我的是type的定义,尤其是最后的助手,它们重复使用了相同的参数。

type BaseEngine<Player> = {players: Player[]}

export type CommandStruct<
  Phase extends string,
  MoveName extends string,
  Player,
  Engine extends BaseEngine<Player> = BaseEngine<Player>,
  AvailableCommandData extends BaseCommandData<MoveName> = BaseCommandData<MoveName>,
  CommandData extends BaseCommandData<MoveName> = BaseCommandData<MoveName>,
> = {
  [phase in Phase]?: {
    [move in MoveName]?: {
      available: (engine: Engine, player: Player) => _AvailableCommandHelper<MoveName, AvailableCommandData, move>,
      valid?: (move: _CommandHelper<MoveName, CommandData, move>, available: _AvailableCommandHelper<MoveName, AvailableCommandData, move>) => boolean
    }
  }
}

export type BaseCommandData<MoveName extends string> = {[key in MoveName]?: any};

export type AvailableCommands<MoveName extends string, AvailableCommandData extends BaseCommandData<MoveName>, PlayerId = number> = {
  [move in MoveName]: _AvailableCommand<MoveName, AvailableCommandData, move, PlayerId>;
}

export type AvailableCommand<MoveName extends string, AvailableCommandData extends BaseCommandData<MoveName>, PlayerId = number> = AvailableCommands<MoveName, AvailableCommandData, PlayerId>[MoveName];

type _CommandHelper<MoveName extends string, CommandData extends BaseCommandData<MoveName>, move extends MoveName> = move extends keyof CommandData ? CommandData[move] : undefined;
type _AvailableCommandHelper<MoveName extends string, AvailableCommandData extends BaseCommandData<MoveName>, move extends MoveName> = move extends keyof AvailableCommandData ? AvailableCommandData[move] | AvailableCommandData[move][] | false : boolean;

type _AvailableCommand<MoveName extends string, AvailableCommandData extends BaseCommandData<MoveName>, move extends MoveName, PlayerId = number> = _CommandHelper<MoveName, AvailableCommandData, move> extends undefined ? {move: move, player: PlayerId} : {move: move, player: PlayerId, data: _AvailableCommandHelper<MoveName, AvailableCommandData, move>};

0 个答案:

没有答案