typescript 如何使类型的泛型键成为不同键的联合类型

oug3syen  于 2022-12-27  发布在  TypeScript
关注(0)|答案(2)|浏览(207)

我没有正确的打字词汇表来描述我试图实现的目标,所以我将使用代码片段来描述我的目标。

interface ActionPayloadTypes {
    FETCH_LIST_REQUEST: any,
    FETCH_LIST_SUCCESS: string[],
    FETCH_LIST_FAILURE: string
}

interface Action <T extends keyof ActionPayloadTypes> {
  type: T
  payload: ActionPayloadTypes[T]
}

我想基于这两个接口创建一个联合类型的Action。
基本上我想

type Actions = Action<'FETCH_LIST_REQUEST'> | Action<'FETCH_LIST_SUCCESS'> | Action<'FETCH_LIST_FAILURE'>

而不必为每个键手动编写联合类型。我尝试使用<keyof ActionPayloadTypes>,它在Action中创建了一个联合类型。见下文。

Action<'FETCH_LIST_REQUEST' | 'FETCH_LIST_SUCCESS' | 'FETCH_LIST_FAILURE'>

我到底做错了什么?

nnt7mjpx

nnt7mjpx1#

type Actions = {
    [A in keyof ActionPayloadTypes]: Action<A>
}[keyof ActionPayloadTypes];

必须将ActionPayloadTypes类型的每个键Map到对Action类型的“调用”中,然后用ActionPayloadTypes的键对这个部分结果进行索引,以获得所需的并集。

yx2lnoni

yx2lnoni2#

你走对了路,正如你所注意到的,Action<keyof ActionPayloadTypes>给你一个类型,其中泛型参数是键的并集。
为了获得Action的每种类型的并集,我将其分为两个步骤:
首先,我使用Map类型获取一个Map,其中包含Action的每种类型的值

type ActionMap = { [K in keyof ActionPayloadTypes]: Action<K> }
    // {
    //     FETCH_LIST_REQUEST: Action<"FETCH_LIST_REQUEST">;
    //     FETCH_LIST_SUCCESS: Action<"FETCH_LIST_SUCCESS">;
    //     FETCH_LIST_FAILURE: Action<"FETCH_LIST_FAILURE">;
    // }

在这里,我可以基于此Map中的值创建一个联合类型

type ActionUnion = ActionMap[keyof ActionMap];
    // Action<"FETCH_LIST_REQUEST"> | Action<"FETCH_LIST_SUCCESS"> | 
    // Action<"FETCH_LIST_FAILURE">

当然,您可以将这些类型组合成单个类型,以使其更加简洁

type ActionUnion = { 
        [K in keyof ActionPayloadTypes]: Action<K> 
    }[keyof ActionPayloadTypes];
    // Action<"FETCH_LIST_REQUEST"> | Action<"FETCH_LIST_SUCCESS"> | 
    // Action<"FETCH_LIST_FAILURE">

相关问题