
TypeScript 无法在运行时直接获取泛型类型 T 的键名,但可通过接收实际对象参数并结合类型断言,静态推导出 keyof T 类型数组。
typescript 无法在运行时直接获取泛型类型 `t` 的键名,但可通过接收实际对象参数并结合类型断言,静态推导出 `keyof t` 类型数组。
在 TypeScript 中,泛型类型参数(如 T)仅存在于编译阶段,运行时会被完全擦除,因此 Object.keys({} as T)、Reflect.ownKeys({} as T) 等写法虽然能通过编译,但实际返回的是 string[],且类型上无法保证与 T 的键精确对应——更严重的是,空对象 {} 并不包含任何自有属性,导致结果恒为空数组,完全丢失类型语义。
✅ 正确做法是:让函数接收一个 T 类型的实际参数,利用 TypeScript 的类型推导能力从实参中提取键信息:
使用 Scrapfly SDK(scrapfly-sdk)在 TypeScript 或 JavaScript 中进行网页抓取,用于用户请求抓取 URL、绕过反爬虫防护、渲染页面等场景。
function getGenericTypeKeys<T extends object>(obj: T): (keyof T)[] {
return Object.keys(obj) as (keyof T)[];
}? 注意:T extends object 约束确保 T 是非原始类型(排除 string/number/null/undefined),使 Object.keys() 调用合法,并支持 keyof T 的精确推导。
✅ 使用示例
interface User {
id: number;
name: string;
active?: boolean;
}
const user = { id: 1, name: "Alice" } as const; // 或普通对象
const keys = getGenericTypeKeys(user);
// 类型为 readonly ["id", "name"](若使用 as const)或 (keyof User)[]
console.log(keys); // ["id", "name"]⚠️ 重要注意事项
- 不可传入空对象字面量 {}:getGenericTypeKeys({}) 会推导为 keyof {} → never[],且运行时返回 [],失去意义;
-
避免无值调用:getGenericTypeKeys
() 不合法——泛型函数必须通过实参推导 T,不能仅靠类型参数; - as (keyof T)[] 是必要断言:因 Object.keys() 返回 string[],而 TypeScript 无法自动将 string[] 缩窄为联合字面量类型(如 "id" | "name"),需显式断言保障类型安全;
- 若需只读字面量类型(如 ["id", "name"] 作为 readonly ["id", "name"]),可结合 as const 声明对象,再配合 keyof typeof obj 提升精度。
✅ 更健壮的变体(支持可选键 & 运行时过滤)
function getOwnKeys<T extends object>(obj: T): Array<keyof T> {
return Object.getOwnPropertyNames(obj) as Array<keyof T>;
}该版本可捕获所有自有属性(包括不可枚举属性),但仍需依赖实参推导 —— 这正是 TypeScript 类型系统与 JavaScript 运行时协同工作的最佳实践:用值承载类型,以运行时输入驱动编译时推导。

















