如何将TypeScript泛型keyof类型转为不同键的联合类型?
自动生成TypeScript Action联合类型的正确方式
你遇到的问题核心是:直接将keyof ActionPayloadTypes传入泛型Action时,TypeScript会把泛型参数视为单一的联合类型,而非对每个键分别实例化Action后再取联合。最终得到的是一个type为联合类型、payload为对应类型联合的单一接口,而非你需要的多个Action实例的联合。
解决方案:使用映射类型+索引访问
通过映射类型遍历ActionPayloadTypes的每个键,为每个键生成对应的Action类型,再通过索引访问取出所有值的联合,就能自动得到目标类型:
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 = { [K in keyof ActionPayloadTypes]: Action<K> }[keyof ActionPayloadTypes]
原理说明
{ [K in keyof ActionPayloadTypes]: Action<K> }是一个映射类型,它会遍历ActionPayloadTypes的每个键K,为每个K生成对应的Action<K>类型,最终得到一个包含所有键值对的类型对象。- 后续的
[keyof ActionPayloadTypes]是索引访问操作,会取出这个映射类型中所有值的联合,也就是Action<'FETCH_LIST_REQUEST'> | Action<'FETCH_LIST_SUCCESS'> | Action<'FETCH_LIST_FAILURE'>,完全符合你的需求。
为什么之前的写法不对?
Action<keyof ActionPayloadTypes> 等价于:
interface CombinedAction { type: 'FETCH_LIST_REQUEST' | 'FETCH_LIST_SUCCESS' | 'FETCH_LIST_FAILURE' payload: any | string[] | string }
这是一个单一接口,其中type和payload都是联合类型,无法保证type和payload的一一对应关系,和你想要的类型语义完全不同。
内容的提问来源于stack exchange,提问作者ioedeveloper
相关产品推荐
相关产品推荐

