Alexander Zeitler
Alexander Zeitler

Reputation: 13089

Function Typing with constraint on Union

I have this code:

export type Command = { aggregateId: string }
export type AddTask = Command & { name: string, dueDate: Date }

export type Commands =
  | AddTask
  | RemoveTask
  | CompleteTask
  | ChangeDueDate

export type Event = { aggregateId: string }
export type TaskAdded = Event & { name: string, dueDate: Date }

export type Events =
  | TaskAdded
  | TaskRemoved
  | TaskCompleted
  | TaskDueDateChanged

export type CommandHandler<T extends Commands> = (command: T) => Events | DomainError

How can I annotate this function to be of type CommandHandler<AddTask>

export function AddTaskCommandHandler (command: AddTask): Events {
  const event: TaskAdded = { aggregateId: command.aggregateId, dueDate: command.dueDate, name: command.name }
  return event
}

Also I want to ensure I can only return an Event which is a member of the Events union.

Upvotes: 0

Views: 38

Answers (1)

SpencerPark
SpencerPark

Reputation: 3506

You can rewrite the function declaration as a var with an anonymous function value. Then explicitly type the var as CommandHandler<AddTask> and typescript will infer/typecheck the value.

export var AddTaskCommandHandler: CommandHandler<AddTask> = function(command) {
    const event: TaskAdded = { aggregateId: command.aggregateId, dueDate: command.dueDate, name: command.name }
    return event
}

Here command is inferred to be AddTask and the return type is checked to be an Events | DomainError.

Upvotes: 1

Related Questions