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

TypeScript如何获取接口中值为undefined的属性的声明类型

问题根因

首先明确核心认知差:

  • TypeScript的类型、接口(interface)仅存在于编译阶段,代码编译为JavaScript运行时,所有类型标注会被完全擦除,没有任何元数据残留。
  • 你代码里调用的typeof是JavaScript原生运行时操作符,只会读取变量当前存储的实际值的类型,你给obj.activityId实际赋值为undefined,运行时输出"undefined"是完全符合JS逻辑的结果,它不可能感知到TS编译阶段定义的接口类型。
  • 你定义的activityId: number | undefined本身就表示该属性的合法值包含undefined,TS不会自动为你保留“排除undefined后的基础类型”的运行时信息。
实现方案

根据你要的是「编译时类型获取」还是「运行时类型读取」,对应方案不同:

1. 仅需要编译时拿到排除undefined后的属性类型

直接用TS内置的NonNullable工具类型,在类型层面提取排除null、undefined后的属性类型即可:

interface activity {
  activityId: number | undefined
}

// 编译时提取属性排除undefined后的类型,此时ActivityIdType等价于number
type ActivityIdType = NonNullable<activity['activityId']>;

// 如果是访问属性时临时告诉TS该值不是undefined,可以用非空断言
const obj: activity = {activityId: undefined};
const id = obj.activityId!; // 编译时id的类型被推导为number

注意:非空断言只是编译阶段跳过TS类型检查的手段,不会改变运行时的实际值,如果运行时obj.activityId真的是undefined,后续代码还是会出现异常。

2. 需要运行时读取到属性声明的预期类型

TS本身不会保留接口的运行时元数据,你需要自己显式维护一份可在运行时访问的类型定义(Schema):

// 这份schema是真实存在的JS对象,运行时可直接访问
const activityFieldType = {
  activityId: "number"
} as const;

interface activity {
  activityId: number | undefined
}

const obj: activity = {activityId: undefined};
console.log(activityFieldType.activityId); // 运行时输出 "number",符合你的预期
console.log(typeof obj.activityId); // 输出实际值的类型 "undefined"

如果需要更复杂的运行时类型校验,可以直接基于这类自定义schema写校验逻辑,不需要依赖TS的类型系统。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 11:42:23