Мне нужно, чтобы тип возвращаемого значения функции менялся в зависимости от значения одного из параметров функции.
Параметр имеет тип Command
, как определено ниже. Цель состоит в том, чтобы сделать его расширяемым, чтобы можно было добавлять больше команд.
type Command = 'trueOrFalse' | 'logSomething';
Существует функция handleCommand(command: Command) => ???
, в которой тип возвращаемого значения будет меняться в зависимости от команды. Однако мне бы хотелось, чтобы он мог определить тип возвращаемого значения, например, когда вы вызываете handleCommand('trueOrFalse')
, он знает, что вернет boolean
.
У меня есть это:
type Command = 'trueOrFalse' | 'logSomething'
type CommandHandler = {
'trueOrFalse': () => boolean;
'logSomething': () => void;
}
type Handlers = {
[Key in Command]: () => ReturnType<CommandHandler[K]>;
}
handleCommand<T extends Command>(command: T): ReturnType<CommandHandler[T]> {
const handlers: Handlers = {
'trueOrFalse': () => true,
'logSomething': () => { console.info('Test') }
}
const handler = handlers[command] as () => ReturnType<CommandHandler[T]>;
if (!handler) {
//error
}
return handler();
}
Однако когда я вызываю эту функцию, независимо от того, передаю ли я 'trueOrFalse'
или 'logSomething'
, тип возвращаемого значения — boolean | void
. Можно ли заставить функцию понимать, что когда 'trueOrFalse'
является аргументом, она должна быть boolean
возвращаемого типа?
Я добавил многое из этого, чтобы устранить ошибки типа внутри функции, такие как тип Handlers
и приведение константы handler
. Теперь сама функция не имеет ошибок типа, но тип возвращаемого значения не тот, который я хочу.
Редактировать:
Хорошо, оказывается, эта проблема связана с наличием промежуточной функции, которая вызывает handleEvent
.
Это посредническая функция.
triggerCommand(command: Command) {
return this.commandDispatcher.handleCommand(command);
}
Вот что вызывает ошибку типа
let bool: boolean;
bool = triggerCommand('trueOrFalse'); // boolean | void cannot be assigned to boolean
Спасибо. Чтобы решить эту проблему, пришлось явно указать тип возвращаемого значения triggerCommand
.
triggerCommand<T extends Command>(command: Command): ReturnType<CommandHandler[T]>
Извините, я не предоставил этот контекст, я не рассматривал эту промежуточную функцию, поскольку она ничего не делает. Понятно, почему это не сработало.
Пожалуйста, отредактируйте , чтобы предоставить минимально воспроизводимый пример, где мы можем ясно увидеть проблему, которую вы видите, когда мы смотрим на нее в наших IDE. Сейчас кажется, что проблемы вообще нет, как показывает предыдущий комментарий, и поэтому вопрос рискует быть закрыт как невоспроизводимый или требующий деталей отладки.
Извините, я забыл, что handleCommand на самом деле вызывался через другую функцию. Обновил вопрос.
Вам просто нужно также сделать triggerCommand
универсальным.
function triggerCommand<T extends Command>(command: T) {
return handleCommand(command);
}
let bool: boolean;
bool = triggerCommand('trueOrFalse'); // fine
Это позволяет получить неявный тип возвращаемого значения из T
вместо всех возможных типов возвращаемого значения.
В чем проблема? он работает правильно: Детская площадка, на самом деле вам даже не нужно утверждать тип, чтобы
handlers[command]