TypeScript遍历对象属性时如何判断key是否为可选属性
TypeScript 判断对象属性可选/必填的解决方案
可选属性、必填属性是 TypeScript 专属的类型层概念,所有类型信息会在编译为 JavaScript 的阶段完全擦除,因此无法直接在运行时代码中通过原生语法判断一个普通对象的属性是可选还是必填。
首先你提供的示例代码存在语法错误:实际给对象赋值时不能给属性加?标识,可选标识仅允许在类型定义中使用,修正后示例如下:
interface TestObject { param: string, foo?: string } // 正确的对象赋值写法 const object: TestObject = { param: "hello", foo: "bar" }
根据使用场景的不同,可选择以下两种实现方案:
场景1:需要在运行时做判断
如果必须在运行时区分属性的可选/必填状态,需要提前定义结构校验规则,手动维护元信息,示例逻辑如下:
// 提前定义对应结构的元信息 const TestObjectMeta = { requiredKeys: ['param'], optionalKeys: ['foo'] } as const const takeAnObject = (object: unknown) => { // 先做类型守卫,确保入参是合法对象 if (typeof object !== 'object' || object === null) return Object.keys(object).forEach((key: string) => { if (TestObjectMeta.optionalKeys.includes(key as typeof TestObjectMeta.optionalKeys[number])) { console.log(`${key} 是可选参数`) } else if (TestObjectMeta.requiredKeys.includes(key as typeof TestObjectMeta.requiredKeys[number])) { console.log(`${key} 是必填参数`) } else { console.log(`${key} 是未定义的未知参数`) } }) }
复杂场景下也可以使用 Zod 这类 Schema 校验库,直接从定义的 Schema 中提取可选、必填属性的元信息,无需手动维护两套规则。
场景2:仅需要在 TypeScript 类型层面做判断
如果不需要运行时逻辑,仅要在类型系统中提取对象类型的可选/必填属性,可以通过类型体操实现:
// 提取对象类型的可选key工具类 type OptionalKeys<T> = { [K in keyof T]-?: {} extends Pick<T, K> ? K : never }[keyof T] // 提取对象类型的必填key工具类 type RequiredKeys<T> = Exclude<keyof T, OptionalKeys<T>> // 测试效果 type TestObject = { param: string, foo?: string } type TestOptionalKeys = OptionalKeys<TestObject> // 计算后类型为 "foo" type TestRequiredKeys = RequiredKeys<TestObject> // 计算后类型为 "param"
内容的提问来源于stack exchange,提问作者sheepiiHD
相关产品推荐
相关产品推荐

