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

如何让TypeScript要求对象需先定义position才能定义innerSize?

TypeScript条件属性依赖类型定义异常解析

问题背景

需要定义一个TypeScript类型,要求仅当对象中存在position属性时,才能定义innerSize属性。尝试了如下联合类型定义:

type TypeA = {
  width?: number;
  height?: number;
  position: string;
  innerSize?: string;
} | {
  width?: number;
  height?: number;
  position?: undefined;
}

但在创建对象时出现不符合预期的情况:

function test() {
  const a: TypeA = {};
  const b: TypeA = { width: 50, height: 75 };
  const c: TypeA = { position: "5, 7" };

  // 报错:Type '{ innerSize: string; }' 无法分配给TypeA,缺少position
  const d: TypeA = { innerSize: "400, 120" };

  const e: TypeA = { width: 50, innerSize: "400, 120" }; // 却能编译通过!
}

疑问:为何仅添加width属性就能绕过position必须存在才能使用innerSize的限制?

原因分析

问题出在联合类型的第二个分支{ width?: number; height?: number; position?: undefined; }:

  • 这个分支只限制了position可选为undefined,但没有对innerSize做任何限制。
  • TypeScript的对象类型默认允许额外属性(除非开启严格额外属性检查或使用精确类型),所以{ width: 50, innerSize: "400, 120" }会被匹配到第二个分支:没有position属性等价于position为undefined,符合分支要求,而额外的innerSize属性不会触发类型检查错误。

而const d: TypeA = { innerSize: "400, 120" }报错,是因为TypeScript在匹配联合类型时,会优先检查对象是否符合某个分支的必填属性,这个对象没有任何分支的必填属性,且第一个分支要求position必须存在,所以会报错;但当添加了width后,对象匹配到第二个分支的可选属性,此时额外属性不会被拦截。

解决方法

在第二个分支中明确禁止innerSize属性,通过innerSize?: never来限制该分支下innerSize只能为undefined或不存在:

type TypeA = {
  width?: number;
  height?: number;
  position: string;
  innerSize?: string;
} | {
  width?: number;
  height?: number;
  position?: undefined;
  innerSize?: never; // 明确禁止innerSize存在
}

修改后,const e: TypeA = { width: 50, innerSize: "400, 120" }会触发预期的类型错误,确保只有存在position时才能定义innerSize。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 08:31:19