When dealing with a union type like ScheduleOrChannel
as shown below:
type AllChanges = CreateChangeLog | DeleteChangeLog
type ScheduleOrChannel = NonNullable<AllChanges["from"]>;
// type ScheduleOrChannel = Schedule | Channel
If you need to filter it to only include members that are of a specific supertype, you can utilize the Extract<T, U>
utility type like this:
type JustSchedule = Extract<ScheduleOrChannel, { flag_active: any }>
// type JustSchedule = Schedule
type JustChannel = Extract<ScheduleOrChannel, { flag_archived: any }>
// type JustChannel = Channel
The Extract<T, U>
is essentially a distributive conditional type implemented in the following way:
type Extract<T, U> = T extends U ? T : never
This allows you to create your custom union-filtering function based on other criteria, such as utilizing a HasKey
utility type:
type HasKey<T, K extends PropertyKey> =
T extends unknown ? K extends keyof T ? T : never : never;
type JustSchedule1 = HasKey<ScheduleOrChannel, "flag_active">
// type JustSchedule1 = Schedule
type JustChannel2 = HasKey<ScheduleOrChannel, "flag_archived">
// type JustChannel2 = Channel
Feel free to experiment and customize your filtering approach using TypeScript!