我想做类似的事情:
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>};