TypeScript如何扩展用户自定义泛型接口以适配Redux Toolkit封装场景?
实现自定义泛型增强State的方案
核心原理
TypeScript 不支持接口直接扩展未知泛型参数,你可以使用*交叉类型(Intersection Type)*实现同等的类型合并效果,基础写法如下:
// T为用户传入的自定义State类型 type EnhancedState<T> = T & { enhancedProp: {} // 所有你要新增的公共属性都在这里定义 }
Redux Toolkit 封装createSlice完整实现
针对你提到的Redux Toolkit场景,完整实现代码如下:
首先引入依赖并定义固定的增强属性类型、入参和返回值类型:
import { createSlice, CreateSliceOptions, Slice } from '@reduxjs/toolkit' // 1. 定义你要新增的请求相关固定属性类型 type RequestEnhancedProps = { enhancedProps: { pendingRequests: number requestErrors: Record<string, string | null> // 其他需要统一添加的属性都可以在这里扩展 } } // 2. 定义包装函数的入参类型,泛型T为用户自定义的初始State类型 type WrappedCreateSliceOptions<T> = Omit<CreateSliceOptions<T, any, string>, 'initialState'> & { initialState: T } // 3. 定义返回的Slice类型,State为用户自定义类型+增强属性的合并类型 type EnhancedSlice<T> = Slice<T & RequestEnhancedProps, any, string> // 4. 实现包装函数 export function createSliceWithRequests<T>(options: WrappedCreateSliceOptions<T>): EnhancedSlice<T> { return createSlice({ ...options, initialState: { ...options.initialState, enhancedProps: { pendingRequests: 0, requestErrors: {} } // 类型断言保证TS识别合并后的State类型正确 } as T & RequestEnhancedProps, reducers: { // 统一的请求处理reducer reducerWhichHandleRequests(state) { state.enhancedProps.pendingRequests++ }, ...options.reducers } }) as EnhancedSlice<T> }
使用示例
用户调用你封装的函数时,只需要传入自定义的State和配置即可,返回的Slice会自动携带合并后的类型:
// 自定义业务State类型 interface BookState { bookList: {id: number, name: string}[] total: number } const bookSlice = createSliceWithRequests({ name: 'books', initialState: { bookList: [], total: 0 } as BookState, reducers: { setBookList(state, action) { state.bookList = action.payload } } }) // 此时bookSlice的state类型同时包含BookState和RequestEnhancedProps的属性 // 可直接访问:state.bookList / state.total / state.enhancedProps.pendingRequests
可选扩展
如果你确实需要用interface形式定义,也可以采用如下写法,不过适用场景比交叉类型更窄,仅推荐在需要声明合并的场景使用:
interface EnhancedState<T> extends T & { enhancedProp: {} } {}
内容的提问来源于stack exchange,提问作者Marco Ripamonti
相关产品推荐
相关产品推荐

