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

如何从已类型化的Partial对象提取实际存在的键而非全部允许键

问题描述

我想从对象中提取实际存在的键列表,同时要求这些键必须属于某个指定的允许值集合。目前只能单独实现其中一项:要么提取所有键(包括无效的),要么限制键在允许范围内但提取出所有允许值而非实际存在的键。

示例1:无类型约束时的键提取

不指定键的类型时,能轻松提取键,但会包含无效值:

// 如果不指定键的类型,我可以轻松提取它们。
const workdayAttributesAuto = {
    Monday: 123,
    Tuesday: 456,
    Floofday: -1,  // 糟糕,我可以指定一个无效的日期
};

// 现在我可以顺利将它们提取为另一个类型,但这里不仅包含Monday和Tuesday,还混入了不需要的无效值。
export type workdayNamesAuto = keyof typeof workdayAttributesAuto;
// --> type workdayNamesAuto = 'Monday' | 'Tuesday' | 'Floofday';

示例2:有类型约束但无法提取实际键

指定类型限制键为允许值后,提取的是所有允许值而非对象中实际存在的键:

type Days = 'Sunday' | 'Monday' | 'Tuesday'; // 仅允许这些键

const workdayAttributes: Partial<Record<Days, number>> = {
    // 故意省略了Sunday
    Monday: 123,
    Tuesday: 456,
    //Floofday: 0,  // 不允许指定无效日期,这很好
};

// 但现在这个类型包含了Sunday,而它并不是对象中的实际键。
export type workdayNames = keyof typeof workdayAttributes;
// --> type workdayNames = 'Sunday' | 'Monday' | 'Tuesday';

如何让keyof typeof仅获取对象中实际指定的键,而非所有允许的可能值?

解决方案

可以通过两种方式实现:既限制键的合法范围,又保留对象的字面量类型,从而提取实际存在的键。

方式一:泛型函数约束(兼容所有TS版本)

创建泛型函数约束对象键的范围,同时让TypeScript推导对象的字面量类型:

type Days = 'Sunday' | 'Monday' | 'Tuesday';

// 泛型函数:约束对象的键只能是Days的子集,同时保留字面量类型
const createRestrictedObject = <T extends Partial<Record<Days, number>>>(obj: T) => obj;

// 创建受约束的对象,无效键会直接报错
const workdayAttributes = createRestrictedObject({
    Monday: 123,
    Tuesday: 456,
    // Floofday: -1, // 此处会触发类型错误,不符合Days约束
});

// 提取实际存在的键
export type workdayNames = keyof typeof workdayAttributes;
// --> type workdayNames = 'Monday' | 'Tuesday';

方式二:satisfies关键字(TS 4.9+)

用satisfies关键字直接检查对象是否符合指定类型,但不改变对象的字面量类型:

type Days = 'Sunday' | 'Monday' | 'Tuesday';

const workdayAttributes = {
    Monday: 123,
    Tuesday: 456,
} satisfies Partial<Record<Days, number>>;

// 提取实际存在的键
export type workdayNames = keyof typeof workdayAttributes;
// --> type workdayNames = 'Monday' | 'Tuesday';

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 02:10:25