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

Next.js(T3栈)中Typescript类型不兼容错误(TS2345)

TS2345类型错误:setSolved状态更新时类型不兼容

问题说明

使用Next.js搭配T3栈开发项目时,遇到Typescript的TS2345类型错误。原因是调用setSolved更新solved状态时,传入的新对象类型与ISolved接口定义不匹配:新对象的difficulty为number | undefined类型、title为string | undefined类型,但ISolved接口要求这两个字段必须是number和string,不允许undefined。

相关代码定义

interface ISolved {
  word: string[];
  difficulty: number;
  title: string;
}
const [solved, setSolved] = useState<ISolved[]>([]);

错误发生代码段

setSolved((prevSolved: ISolved[]) => {
  const newSolvedItem = {
    word: selected,
    difficulty: data?.find((item) => item.wordString === selected[0])?.difficulty,
    title: getDifficultyTitle(
      data?.find((item) => item.wordString === selected[0])?.difficulty ?? 0
    ),
  };

  return prevSolved ? [...prevSolved, newSolvedItem] : [newSolvedItem];
});

尝试过的错误写法

setSolved([
  ...solved,
  ...data?.sort((a, b) => a.difficulty - b.difficulty),
]);

数据模型结构

model GameWords {
    id          String @id @default(uuid())
    words       Word[]
    easyTitle   String
    mediumTitle String
    hardTitle   String
    trickyTitle String
}

model Word {
    id          String     @id @default(cuid())
    wordString  String
    difficulty  Int
    GameWords   GameWords? @relation(fields: [gameWordsId], references: [id])
    gameWordsId String?
}

解决方案

方案1:确保找到目标Word后再创建新项

先获取匹配的Word对象,若未找到则不执行更新(或根据业务逻辑处理),从根源保证类型符合要求:

setSolved((prevSolved: ISolved[]) => {
  // 定位匹配的Word对象
  const targetWord = data?.find((item) => item.wordString === selected[0]);
  // 未找到则返回原状态,终止更新
  if (!targetWord) return prevSolved;

  const newSolvedItem = {
    word: selected,
    difficulty: targetWord.difficulty, // 类型确定为number
    title: getDifficultyTitle(targetWord.difficulty), // 传入确定数值,title类型为string
  };

  return [...prevSolved, newSolvedItem];
});

方案2:给undefined情况设置默认值

如果业务允许未找到时使用默认值,通过??运算符给difficulty指定默认数值,强制类型转为number:

setSolved((prevSolved: ISolved[]) => {
  const targetDifficulty = data?.find((item) => item.wordString === selected[0])?.difficulty ?? 0;
  
  const newSolvedItem = {
    word: selected,
    difficulty: targetDifficulty, // 经过默认值处理后类型为number
    title: getDifficultyTitle(targetDifficulty), // 传入确定数值,title为string
  };

  return [...prevSolved, newSolvedItem];
});

额外说明

  • 方案1更严谨,适合必须找到对应Word才能添加的业务场景;
  • 方案2适合允许使用默认值的场景,需确保getDifficultyTitle函数接收number参数时返回确定的string类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 21:27:39