无需外部包,如何遍历TypeScript接口的所有键?
获取TypeScript接口所有键的原生方案
嘿,这个问题确实挺常见的,而且不少旧回答没讲透核心——先明确一个关键点:TypeScript接口是编译时类型,编译后会被完全擦除,所以没办法直接在运行时“读取”接口本身的键。不过咱们完全可以利用TS的类型系统特性,配合一点原生JavaScript代码实现类似效果,全程不需要任何外部包。
下面给你几个实用的原生方案:
方案1:用const断言+类型约束同步键数组
如果能定义一个和接口结构匹配的常量数组,我们可以通过keyof类型来确保数组元素和接口键完全一致,同时这个数组就能在运行时直接使用:
// 先定义你的接口 interface User { id: number; name: string; email: string; } // 创建一个和接口键完全对应的常量数组,用as const锁定类型 const userKeys = ['id', 'name', 'email'] as const; // 加个类型检查,确保数组元素和接口键完全匹配 // 要是后续接口修改,数组没同步,TS会直接报错 type UserKeyType = keyof User; type ArrayKeyType = typeof userKeys[number]; type _EnsureMatch = ArrayKeyType extends UserKeyType ? true : false; // 运行时直接用这个数组就行 console.log(userKeys); // 输出 ["id", "name", "email"]
这个方案的优点是类型绝对安全,接口和键数组的一致性由TS编译器保证,不会出现漏改或错改的情况。
方案2:用类模拟接口(适合需要实例的场景)
如果你的接口逻辑适合用类来承载,那可以通过类实例来获取键:
// 用类实现接口(或者直接把类当类型用) class User { id!: number; name!: string; email!: string; } // 创建一个空实例(不需要赋值,我们只需要它的属性结构) const emptyUser = new User(); // 获取实例的所有自身属性键 const userKeys = Object.getOwnPropertyNames(emptyUser); console.log(userKeys); // 输出 ["id", "name", "email"]
要是类有继承的属性,Object.getOwnPropertyNames只会返回自身的属性;如果要包含继承的属性,可以换成Object.keys或者Reflect.ownKeys,不过通常接口对应的都是自身属性。
方案3:通过对象实例推断键
如果你手里已经有一个符合接口类型的对象,可以写个简单的辅助函数,利用类型推断获取键:
interface User { id: number; name: string; email: string; } // 辅助函数,约束输入对象的类型,并返回键的类型数组 function getKeys<T>(obj: T): (keyof T)[] { // 这里用类型断言,因为Object.keys返回的是string[],我们要把它转成keyof T[] return Object.keys(obj) as (keyof T)[]; } // 传入一个符合User接口的对象 const sampleUser: User = { id: 1, name: "John", email: "john@example.com" }; const userKeys = getKeys(sampleUser); console.log(userKeys); // 输出 ["id", "name", "email"]
这个方案不需要手动维护键数组,只要对象符合接口,TS就会自动推断出所有键的类型,适合已经有实例对象的场景。
重要提醒
再强调一遍:TypeScript接口只存在于编译阶段,所以所有“获取接口键”的方案,本质上都是通过运行时存在的实体(常量数组、类实例、对象)来映射接口的类型,而不是直接读取接口本身。这几个方案都完全依赖TS和JS的原生特性,不需要任何外部包。
内容的提问来源于stack exchange,提问作者Nikos Iliakis
相关产品推荐
相关产品推荐

