You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Typescript编写Redux reducer时,action的any类型应替换为什么?

原生Action类型仅包含type属性,没有你自定义的额外字段,所以访问action.homePageMovies这类属性会抛出类型错误。你可以通过两种方案解决这个问题:


方案1:手动定义Action联合类型(无额外依赖,无需改动现有业务逻辑)

首先为每一种Action定义专属类型,再组合成联合类型替换原有的any:

// 在reducer文件顶部,导入常量后新增以下类型定义
interface AddHomePageMoviesAction {
  type: typeof ADD_HOME_PAGE_MOVIES
  homePageMovies: any[] // 可替换为你的电影对象实际类型,比如Movie[]
}

interface ChangeSelectedMovieAction {
  type: typeof CHANGE_SELECTED_MOVIE
  selectedMovie: number
}

interface IsMoviePageOpenedAction {
  type: typeof IS_MOVIE_PAGE_OPENED
  isMoviePageOpened: boolean
}

interface SearchedMovieAction {
  type: typeof SEARCHED_MOVIE
  searchedMovie: string
}

interface CurrentPageAction {
  type: typeof CURRENT_PAGE
  currentPage: number
}

// 组合为所有合法Action的联合类型
type AppAction = 
  | AddHomePageMoviesAction
  | ChangeSelectedMovieAction
  | IsMoviePageOpenedAction
  | SearchedMovieAction
  | CurrentPageAction

之后把reducer的参数类型替换即可:

// 把action: any改为action: AppAction
function rootReducer( state = initialState, action: AppAction ){
  // 原有逻辑完全不需要改动
  switch(action.type) {
    // ... 原有case代码
  }
}

TS会自动根据action.type的判断收窄类型,每个case分支下的action属性都会有正确的类型提示,不会再报属性不存在的错误。


方案2:使用Redux Toolkit(官方推荐写法,大幅简化类型维护)

如果是新开发项目,推荐使用Redux官方主推的Redux Toolkit,内置了完善的TS类型支持,不需要手动定义大量Action类型:

import { createSlice, PayloadAction } from '@reduxjs/toolkit'

// 定义初始状态,可直接标注类型
const initialState = {
    homePageMovies: [] as any[], // 替换为你的电影对象实际类型
    selectedMovie: 0,
    isMoviePageOpened: false,
    searchedMovie: '',
    currentPage: 1
}

const movieSlice = createSlice({
  name: 'movie',
  initialState,
  reducers: {
    addHomePageMovies: (state, action: PayloadAction<typeof initialState.homePageMovies>) => {
      state.homePageMovies = action.payload
    },
    changeSelectedMovie: (state, action: PayloadAction<number>) => {
      state.selectedMovie = action.payload
    },
    isMoviePageOpened: (state, action: PayloadAction<boolean>) => {
      state.isMoviePageOpened = action.payload
    },
    searchedMovie: (state, action: PayloadAction<string>) => {
      state.searchedMovie = action.payload
    },
    currentPage: (state, action: PayloadAction<number>) => {
      state.currentPage = action.payload
    }
  }
})

// 自动生成类型安全的action creator
export const { addHomePageMovies, changeSelectedMovie, isMoviePageOpened, searchedMovie, currentPage } = movieSlice.actions

export default movieSlice.reducer
export type RootState = ReturnType<typeof movieSlice.reducer>

这种写法不需要手动维护Action联合类型,也避免了手动编写大量switch case的冗余代码,开发效率和类型安全性更高。


内容的提问来源于stack exchange,提问作者rumon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 12:06:01