Вы хотите, чтобы FilterActionByType<A, T>
взял тип объединения A
и воздействовал на каждого члена в отдельности, а затем взял все результаты и объединил их в новый союз ... это означает, что вы хотите от FilterActionByType<A, T>
до распределить по союзам (по крайней мере, в A
). Для этого вы можете использовать дистрибутивные условные типы , убедившись, что ваш условный тип имеет форму type FilterActionByType<A, T> = A extends ...
. Наличие в качестве отмеченного типа A
запускает нужный вам дистрибутив.
Но: ваш условный тип имеет форму type FilterActionByType<A, T> = A["type"] extends ...
, в которой A
«облечен» поиском свойств и поэтому не является дистрибутивным. Это означает, что A["type"] extends ActionType
принимает целое значение объединения для A
, а именно (в вашем случае) ActionUnion
. И ActionUnion["type"] extends "count/get"
становится ("count/get" | "count/set") extends "count/get"
, что ложно. (X extends (X | Y)
всегда верно, но (X | Y) extends X
вообще неверно.) Таким образом, вы получаете never
.
Самый простой способ изменить то, что у вас есть, на дистрибутивный условный тип - это просточтобы обернуть ваше определение в A extends any ? ... : never
:
export type FilterActionByType<
A extends AnyAction,
ActionType extends string
> = A extends any ? A['type'] extends ActionType ? A : never : never;
type ActionUnion = Action<'count/get'> | Action<'count/set'>;
type CountGetAction = FilterActionByType<ActionUnion, 'count/get'>;
// type CountGetAction = Action<"count/get">
Или вы можете изменить свой исходный условный тип на дистрибутивный, не оборачивая его:
export type FilterActionByType<
A extends AnyAction,
ActionType extends string
> = A extends { type: ActionType } ? A : never;
type CountGetAction = FilterActionByType<ActionUnion, 'count/get'>;
// type CountGetAction = Action<"count/get">
Проверка A extends {type: ActionType}
является дистрибутивомверсия A["type"] extends ActionType
.
Любой способ должен работать для вас, но последний, вероятно, чище.
Хорошо, надеюсь, это поможет;удачи!
Ссылка на код