gpt4 book ai didi

typescript - 如何在Typescript中按属性过滤对象类型的联合?

转载 作者:行者123 更新时间:2023-12-03 20:13:54 24 4
gpt4 key购买 nike

想象一下以下简化设置:

import { Action, AnyAction } from 'redux'; // interface Action<Type> { type: Type } and type AnyAction = Action<any>

export type FilterActionByType<
A extends AnyAction,
ActionType extends string
> = A['type'] extends ActionType ? A : never;

type ActionUnion = Action<'count/get'> | Action<'count/set'>;

type CountGetAction = FilterActionByType<ActionUnion, 'count/get'>;
// expected: Action<'count/get'>
// received: never


有没有办法做到这一点? ( typescript 3.7 是一个选项)

最佳答案

您希望 FilterActionByType<A, T> 采用联合类型 A 并分别作用于每个成员,然后获取所有结果并将它们联合到一个新联合中……这意味着您希望 FilterActionByType<A, T> 分布在联合上(至少在 A 中)。您可以使用 distributive conditional types 来执行此操作,方法是确保您的条件类型的形式为 type FilterActionByType<A, T> = A extends ... 。将裸 A 作为检查类型触发您想要的分发。

但是:您的条件类型的形式为 type FilterActionByType<A, T> = A["type"] extends ... ,其中 A 被属性查找“覆盖”,因此不是分布式的。这意味着 A["type"] extends ActionType 获取 A 的整个联合值,即(在您的情况下) ActionUnionActionUnion["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 的分发版本。

无论哪种方式都适合您,但后者可能更干净。

好的,希望有帮助;祝你好运!

Link to code

关于typescript - 如何在Typescript中按属性过滤对象类型的联合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58584071/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com