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

TypeScript中const对象类型访问可选属性报错如何解决?

解决TypeScript中访问联合类型属性的类型错误

问题场景

你定义了一个带有as const的只读对象,遍历其键数组时,访问部分键对应的对象的可选属性时触发类型错误,即使使用"optional" in判断也无法解决:

const props = {
  a: {
    optional: "foo",
    mandatory: "bar",
  },
  b: {
    mandatory: "blaz",
  },
} as const;

const propsICareAbout: (keyof typeof props)[] = [];

for (const prop of propsICareAbout) {
  if (props[prop].optional) {
    doStuff(props[prop].optional);
  }
}

报错信息:

Property 'optional' does not exist on type '{ readonly mandatory: "blaz"; }'.

原因分析

as const将props的类型锁定为精确的只读字面量联合类型:typeof props['a'] | typeof props['b']。其中typeof props['b']没有optional属性,TypeScript无法通过"optional" in自动缩小联合类型的范围,因此直接访问会触发类型检查错误。

解决方案

方案1:自定义类型守卫(推荐)

编写类型守卫函数,明确告诉编译器当条件满足时,当前对象包含optional属性:

const props = {
  a: {
    optional: "foo",
    mandatory: "bar",
  },
  b: {
    mandatory: "blaz",
  },
} as const;

const propsICareAbout: (keyof typeof props)[] = [];

// 自定义类型守卫,判断对象是否包含optional属性
function hasOptional(obj: typeof props[keyof typeof props]): obj is typeof props['a'] {
  return "optional" in obj;
}

for (const prop of propsICareAbout) {
  const currentProp = props[prop];
  if (hasOptional(currentProp)) {
    doStuff(currentProp.optional); // 类型检查通过
  }
}

function doStuff(str: string) {
  console.log(str);
}

方案2:类型断言(适合逻辑确定的场景)

直接通过类型断言指定当前对象为包含optional属性的类型,跳过类型检查:

const props = {
  a: {
    optional: "foo",
    mandatory: "bar",
  },
  b: {
    mandatory: "blaz",
  },
} as const;

const propsICareAbout: (keyof typeof props)[] = [];

for (const prop of propsICareAbout) {
  const currentProp = props[prop];
  if ("optional" in currentProp) {
    // 断言为包含optional的类型
    doStuff((currentProp as typeof props['a']).optional);
  }
}

function doStuff(str: string) {
  console.log(str);
}

方案3:统一类型定义(牺牲精确性换简洁)

提前定义包含可选optional属性的类型,让所有对象都遵循该类型,避免联合类型的问题:

// 定义统一的属性类型,optional为可选属性
type PropItem = {
  mandatory: string;
  optional?: string;
};

const props: Record<string, PropItem> = {
  a: {
    optional: "foo",
    mandatory: "bar",
  },
  b: {
    mandatory: "blaz",
  },
} as const;

const propsICareAbout: (keyof typeof props)[] = [];

for (const prop of propsICareAbout) {
  if (props[prop].optional) {
    doStuff(props[prop].optional); // 类型检查通过
  }
}

function doStuff(str: string) {
  console.log(str);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 14:42:08