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
相关产品推荐
相关产品推荐

