I'm having issues with conditional types.
I require that when filter[triggerType]
on AutomationParams
changes, filter[triggerId]
values also update to the proper kind.
For instance, when filter[triggerType]
equals corn
, the alternatives for filter[triggerId]
are limited to being of the CronTriggerId
type.
type TriggerType = 'event' | 'cron' | 'scheduled';
type EventTriggerId = 'extendStayRequired' | 'reservationAccessChanged'
type CronTriggerId = 'reservationsCron';
type ScheduledTriggerId = 'reservationCheckedIn';
type TriggerId<T> = T extends 'event'
? EventTriggerId
: T extends 'cron'
? CronTriggerId
: T extends 'scheduled'
? ScheduledTriggerId
: never;
type AutomationParams = {
'filter[triggerType]': TriggerType;
'filter[triggerId]': TriggerId<TriggerType>;
};
const obj: AutomationParams = {
'filter[triggerType]': 'cron',
'filter[triggerId]': 'extendStayRequired',
};
Additionally, this is the playground.
CodePudding user response:
I would suggest to rewrite TriggerId
to just be a simple lookup map.
type TriggerMap = {
event: EventTriggerId
cron: CronTriggerId
scheduled: ScheduledTriggerId
}
AutomationParams
can now be calculated to be a union of all valid combinations.
type AutomationParams = {
[K in keyof TriggerMap]: {
'filter[triggerType]': K;
'filter[triggerId]': TriggerMap[K];
}
}[keyof TriggerMap]
CodePudding user response:
AutomationParams should itself be a union :
type EventTriggerId = 'extendStayRequired' | 'reservationAccessChanged'
type CronTriggerId = 'reservationsCron';
type ScheduledTriggerId = 'reservationCheckedIn';
type AutomationParams = {
'filter[triggerType]': 'event';
'filter[triggerId]': EventTriggerId;
} | {
'filter[triggerType]': 'cron';
'filter[triggerId]': CronTriggerId;
} | {
'filter[triggerType]': 'scheduled';
'filter[triggerId]': ScheduledTriggerId;
};
const obj: AutomationParams = {
'filter[triggerType]': 'scheduled',
'filter[triggerId]': 'reservationCheckedIn',
};
console.log(obj)
Or use mapping interface :
type TriggerType = 'event' | 'cron' | 'scheduled';
type EventTriggerId = 'extendStayRequired' | 'reservationAccessChanged'
type CronTriggerId = 'reservationsCron';
type ScheduledTriggerId = 'reservationCheckedIn';
export interface AutomationParams<T extends TriggerType> {
'filter[triggerType]': T
'filter[triggerId]': TriggerId[T]
}
type TriggerId ={
'event': EventTriggerId,
'cron': CronTriggerId,
'scheduled': ScheduledTriggerId
}
const obj: AutomationParams<'event'> = {
'filter[triggerType]': 'event',
'filter[triggerId]': 'extendStayRequired',
};
console.log(obj)
You could also do it with conditional types:
type TriggerType = 'event' | 'cron' | 'scheduled';
type EventTriggerId = 'extendStayRequired' | 'reservationAccessChanged'
type CronTriggerId = 'reservationsCron';
type ScheduledTriggerId = 'reservationCheckedIn';
type TriggerId<T> = T extends 'event'
? EventTriggerId
: T extends 'cron'
? CronTriggerId
: T extends 'scheduled'
? ScheduledTriggerId
: never;
type AutomationParams<T extends TriggerType> = {
'filter[triggerType]': T;
'filter[triggerId]': TriggerId<T>;
};
const obj: AutomationParams<'cron'> = {
'filter[triggerType]': 'cron',
'filter[triggerId]': 'reservationsCron',
};