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

能否在编译时提取TypeScript类型的键?

问题解答

首先明确:原生TypeScript无法直接通过KeysOf<FooBar>()这种语法从编译时类型提取运行时的键数组。因为TypeScript的类型系统完全是编译时概念,编译后所有类型信息都会被擦除,不会在最终的JavaScript代码中留下任何痕迹,所以没办法直接从类型生成运行时可用的数组。

不过有几种可行的替代方案,能实现“让类型和运行时键保持一致”的需求:

方案1:从运行时对象推导类型(推荐)

先定义运行时的对象,再通过typeof推导对应的类型,同时直接从对象提取键数组:

// 先定义运行时对象
const fooBarSample = {
    foo: 3,
    bar: 2
};

// 从对象推导类型
type FooBar = typeof fooBarSample;

// 获取类型安全的键数组,用类型断言确保类型正确
const keys = Object.keys(fooBarSample) as Array<keyof FooBar>;

function isFooBar(obj: any): boolean {
    return keys.every(key => key in obj);
}

这种方案的优势是类型和运行时数据完全同步,不需要手动维护两份内容,避免不一致。

方案2:用枚举关联类型与运行时

枚举在TypeScript编译后会保留运行时表示,所以可以用枚举定义键,再基于枚举构建类型:

// 定义枚举作为键的唯一来源
enum FooBarKeys {
    Foo = 'foo',
    Bar = 'bar'
}

// 基于枚举构建类型
type FooBar = {
    [FooBarKeys.Foo]: number;
    [FooBarKeys.Bar]: number;
};

// 从枚举提取运行时键数组
const keys = Object.values(FooBarKeys);

function isFooBar(obj: any): boolean {
    return keys.every(key => key in obj);
}

这种方案适合需要明确管理键集合的场景,枚举可以统一控制键的命名和值。

方案3:自定义编译转换器(进阶)

如果项目中有大量类似需求,可以使用第三方工具(如ts-transformer-keys),它能在编译阶段自动从类型生成对应的运行时键数组。不过这种方式需要修改TypeScript的编译配置,添加自定义transformer,依赖特定的构建工具链(如webpack、Rollup)。

示例配置后用法:

import { keys } from 'ts-transformer-keys';

type FooBar = {
    foo: number;
    bar: number;
};

// 编译时会自动生成["foo", "bar"]的运行时数组
const keys = keys<FooBar>();

function isFooBar(obj: any): boolean {
    return keys.every(key => key in obj);
}

注意:这不是TypeScript原生支持的功能,需要额外配置工具链。


内容的提问来源于stack exchange,提问作者Alessandro Tornesi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 22:20:13