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

为何TypeScript在此示例中未触发类型不匹配错误?

TypeScript类型兼容性:多余字段不报错、缺失字段报错的原因

场景一:源类型有额外字段,赋值不报错

先看你的代码定义:

type CardInfo = {
  cardIndex: null | number;
  title: string;
  note: string;
  _id: string;
  from: string;
  cardId: string;
};

type ContentType = {
  title: string;
  note: string;
  _id: string;
  cardId: string;
};

type ContentForFullScreen = ContentType & {
  cardIndex: number | null;
};

const App: FC = () => { 
  const [cardInfo, setCardInfo] = useState<CardInfo>({
    cardIndex: null,
    title: "",
    note: "",
    _id: "",
    from: "",
    cardId: "",
  });

 const [fullScreenCardData, setFullScreenCardData] =
    useState<ContentForFullScreen>(cardInfo);
}

这里CardInfo比ContentForFullScreen多了from字段,但赋值时TypeScript不报错,核心原因是TypeScript采用结构类型系统(鸭子类型):

  • 只要源值的结构包含目标类型的所有必填属性,就认为类型兼容,额外的属性不会阻断赋值。
  • 另外,这里的cardInfo是已经被明确标注为CardInfo类型的变量,不是直接传入的对象字面量,所以不会触发TypeScript对对象字面量的「额外属性检查」——如果是直接写useState<ContentForFullScreen>({cardIndex: null, title: "", ..., from: ""})这种对象字面量,才会因为额外字段报错,而变量形式会跳过这个检查。

场景二:目标类型有源类型没有的字段,赋值报错

当你给ContentForFullScreen新增必填字段age后:

type ContentForFullScreen = ContentType & {
  cardIndex: number | null;
  age: number;
};

此时赋值useState<ContentForFullScreen>(cardInfo)会报错,原因很直接:

  • ContentForFullScreen要求必须存在age字段且类型为number,但CardInfo没有定义这个属性,cardInfo变量自然也不包含该字段,完全不满足目标类型的结构要求,所以TypeScript会抛出类型不兼容的错误。

简单总结

  • 结构类型系统只关注「是否满足目标类型的所有要求」,多余属性不影响兼容性;
  • 但如果缺少目标类型要求的必填属性,必然触发类型错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 08:57:27