Я хотел бы сделать что-то вроде:
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>
}
}
В основном я хочу повторно использовать общие c аргументы вместо того, чтобы повторять их каждый раз. Я не хочу делать что-то вроде:
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>;
}
Другой способ описать это - эквивалент вложенного typedef
в C ++:
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>};