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

开启exactOptionalPropertyTypes后Object.hasOwn的TS undefined错误原因

问题原因及解决方案

第一个错误(ts(18048):shape.radius可能为undefined)

开启exactOptionalPropertyTypes后,TypeScript对可选属性的语义做了严格限制:可选属性要么完全不存在,要么存在且值必须符合属性的非undefined类型(比如radius?: number等价于「无radius属性」或「有radius且值为number」)。但目前TypeScript的内置类型守卫(Object.hasOwn)没有和这个配置联动,即使检测到属性存在,TypeScript也无法自动将对象类型窄化为「包含该属性且值非undefined」的类型,所以仍然会提示可能为undefined。

解决办法

自定义一个类型守卫函数,明确告诉TypeScript检测到属性存在时的类型:

interface Shape {
  radius?: number;
}

function hasOwnProp<T extends object, K extends PropertyKey>(obj: T, key: K): obj is T & Record<K, Exclude<T[K], undefined>> {
  return Object.hasOwn(obj, key);
}

function getArea(shape: Shape) {
  if (hasOwnProp(shape, 'radius')) {
    // 这里shape.radius会被正确推断为number,不再提示undefined
    return Math.PI * shape.radius ** 2;
  }
  return 0;
}

第二个错误(ts(2375):类型不兼容)

同样是exactOptionalPropertyTypes的严格限制导致的:当你定义radius?: number时,TypeScript不允许该属性存在且值为undefined——可选属性的语义是「可省略」,而非「存在时可以为undefined」。所以{ radius: undefined }不符合Shape的类型定义。

解决办法

如果业务场景确实需要属性存在但值可以为undefined,不要用可选属性语法,直接把属性类型定义为number | undefined(必须存在该属性):

interface Shape {
  radius: number | undefined;
}

// 现在可以正常创建该对象,不会报错
const s1: Shape = { radius: undefined };

如果不需要属性必须存在,那就不要给radius赋值undefined,直接省略该属性:

const s1: Shape = {}; // 符合类型定义

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 21:00:15