TypeScript中如何向索引访问类型传递泛型?Redux工厂类型重构场景
实现方案
你只需要将CommonFactory内部的属性定义为可接收键泛型参数的类型即可,不需要在Factory初始化时传参,使用时通过泛型传入要拾取的State键即可,完整实现如下:
1. 改造CommonFactory定义
import type { Action, ActionCreator as ReduxActionCreator } from 'redux' type CommonFactory<T, S> = { // 泛型参数K为要拾取的AppState键,支持传入联合类型选多个键 Payload<K extends keyof S>: Pick<S, K>; Action<K extends keyof S>: Action<T> & { payload: CommonFactory<T, S>['Payload'][K] }; ActionCreator<K extends keyof S>: ReduxActionCreator<CommonFactory<T, S>['Payload'][K]>; }
如果你的TS版本 >=4.7,也可以用interface写法,和你原来的写法更接近:
import type { Action, ActionCreator as ReduxActionCreator } from 'redux' interface CommonFactory<T, S> { Payload<K extends keyof S>: Pick<S, K>; Action<K extends keyof S>: Action<T> & { payload: this['Payload'][K] }; ActionCreator<K extends keyof S>: ReduxActionCreator<this['Payload'][K]>; }
2. 业务类型定义和你原来的写法完全兼容
interface AppState { key1: any; key2: any; key3: any; } // 替换为你实际的Action Type联合类型/枚举 type AppTypes = string; type Factory = CommonFactory<AppTypes, AppState>; // 导出的类型本身带泛型参数,使用时传入要选的键即可 type AppPayload<K extends keyof AppState> = Factory['Payload'][K]; type AppAction<K extends keyof AppState> = Factory['Action'][K]; type AppActionCreator<K extends keyof AppState> = Factory['ActionCreator'][K];
3. 使用效果和你期望的完全一致
const SOME_ACTION_TYPE = 'app/updateKey1'; const someActionCreator: AppActionCreator<'key1'> = (payload) => { return { type: SOME_ACTION_TYPE, // payload会自动推导为{ key1: any },类型错误会直接提示 payload: { key1: payload.key1 } } } // 支持选多个键 const updateTwoKeys: AppActionCreator<'key1' | 'key2'> = (payload) => ({ type: 'app/updateTwo', payload: { key1: payload.key1, key2: payload.key2 } })
可选扩展
如果需要保留原来Partial的可选属性效果,只需要修改Payload的定义即可:
Payload<K extends keyof S>: Partial<Pick<S, K>>;
内容的提问来源于stack exchange,提问作者C. B. Prosser
相关产品推荐
相关产品推荐

