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

TS2345报错:类型'{}'缺少Movie类型所需属性如何解决

问题根因

TS2345报错的核心原因是Redux中Movies_State类型定义的movies_list字段被标注为object[](普通对象数组),而非Movie[]类型,导致TS推导MoviesList的元素类型为无属性的空对象{},此时给map回调参数手动标注Movie类型,就会触发类型不兼容的校验错误。
另外代码里还存在两个容易引发后续问题的隐患:

  • Movie接口在CardI.tsx和App.tsx中重复定义,后续字段调整时很容易出现两边类型不一致的问题
  • 遍历渲染时key属性写在了组件内部的MUI Card标签上,不符合React要求key绑定在循环直接子元素的规则,会触发运行时警告
排查步骤
  • 打开./redux/reducers/MoviesReducer文件,检查Movies_State接口中movies_list字段的类型,确认是否被误写为object[],或因缺省类型被TS默认推导为object[]
  • 检查useSelector的泛型参数与根state路径是否匹配,若state路径写错也可能导致拿到的类型不符合预期
  • 确认两个文件中重复定义的Movie接口字段是否完全一致,避免后续维护出现类型偏差
修复方案
  1. 抽离公共类型,避免重复定义
    新建src/types/index.ts文件存放全局共用的接口定义:
// src/types/index.ts
export interface Movie {
  title: string;
  image: string;
  id: string;
  description: string;
}
  1. 修正Redux State类型
    在MoviesReducer文件中引入公共Movie类型,给movies_list指定正确的数组类型:
// src/redux/reducers/MoviesReducer.ts
import { Movie } from '../../types';
// 其余reducer逻辑保持不变
export interface Movies_State {
  // 将原有的movies_list: object[] 替换为以下定义
  movies_list: Movie[];
  // 其余state字段按原有逻辑保留
}
  1. 修正组件代码
  • 删掉CardI.tsx和App.tsx中本地重复定义的Movie接口,统一从公共类型文件引入
  • 去掉map回调中多余的参数类型标注,TS会自动根据MoviesList的类型推导元素类型
  • 将key属性移到循环渲染的直接子组件上

修正后的CardI.tsx代码:

import {
  Card,
  CardHeader,
  CardMedia,
  CardContent,
  Typography,
} from "@mui/material";
import { Movie } from '../types';

const CardI = (props : Movie) => {
  return (
    <Card sx={{ maxWidth: 345, minWidth: 200, marginTop: "15px" }}>
      <CardHeader title={props.title} />
      <CardMedia
        component="img"
        height="194"
        image={props.image}
        alt={props.title}
      />
      <CardContent>
        <Typography variant="body2" color="text.secondary">
          {props.description}
        </Typography>
      </CardContent>
    </Card>
  );
};
export default CardI;

修正后的App.tsx代码:

import React from "react";
import AppBar from "./components/AppBar";
import { Box } from "@mui/material";
import Card from "./components/Card";
import "./App.css";
import { Movies_State } from "./redux/reducers/MoviesReducer";
import { useSelector } from "react-redux";

function App() {
  // 按你实际配置的store根state结构调整state的取值路径
  const MoviesList = useSelector(
    (state: { movies: Movies_State }) => state.movies.movies_list
  );
  return (
    <div className="App">
      <AppBar />
      <br />
      <br />
      <Box justifyContent={"space-around"} flexWrap={"wrap"} display={"flex"}>
        <React.Fragment>
          {MoviesList.length > 0 &&
            MoviesList.map((el) => {
              return <Card key={el.id} {...el} />;
            })}
        </React.Fragment>
      </Box>
    </div>
  );
}

export default App;

提示:如果你的Redux配置了正确的根state类型(比如通过combineReducers自动推导,或者手动定义了RootState类型),useSelector不需要手动写泛型参数,TS会自动推导返回值类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 16:06:23