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

如何在TypeScript中使用keyof typeof正确定义Record类型?

问题描述

我定义了一个类枚举风格的TIMEOFDAY对象,尝试基于这些条目创建正确的Record类型:

export const TIMEOFDAY = {
    FirstLight: 'First Light',
    Morning: 'Morning',
    Antemeridiem: 'Antemeridiem',
    Zenith: 'Zenith',
    Postmeridiem: 'Postmeridiem',
    Evening: 'Evening',
    LastLight: 'Last Light',
    Night: 'Night',
}

但创建Record时TypeScript提示所有键缺失,无法识别通过TIMEOFDAY.FirstLight引用的键,相关代码及错误如下:

type TimeOfDayData = {
    phase: number
    hours: number
    lux: number
    temperature: number
}

type TimeOfDayDataRecord = Record<keyof typeof TIMEOFDAY, TimeOfDayData>

const TIMEOFDAYDATA: TimeOfDayDataRecord = {
    [TIMEOFDAY.FirstLight]: /*   */ { phase: 1, temperature: 10, hours: 5, lux: 1 },
    [TIMEOFDAY.Morning]: /*      */ { phase: 2, temperature: 23, hours: 8, lux: 100 },
    [TIMEOFDAY.Antemeridiem]: /* */ { phase: 3, temperature: 42, hours: 13, lux: 300 },
    [TIMEOFDAY.Zenith]: /*       */ { phase: 4, temperature: 55, hours: 16, lux: 500 },
    [TIMEOFDAY.Postmeridiem]: /* */ { phase: 3, temperature: 48, hours: 22, lux: 300 },
    [TIMEOFDAY.Evening]: /*      */ { phase: 2, temperature: 32, hours: 25, lux: 100 },
    [TIMEOFDAY.LastLight]: /*    */ { phase: 1, temperature: 15, hours: 30, lux: 1 },
    [TIMEOFDAY.Night]: /*        */ { phase: 0, temperature: -10, hours: 33, lux: 0 },
}

错误信息:
Type '{ [x: string]: { phase: number; temperature: number; hours: number; lux: number; }; }' is missing the following properties from type 'TimeOfDayDataRecord': Morning, Antemeridiem, Zenith, Postmeridiem, and 4 more.ts(2740)

问题原因

keyof typeof TIMEOFDAY获取的是TIMEOFDAY对象的属性名(如FirstLight、Morning这类字符串字面量),但你在TIMEOFDAYDATA中用的是TIMEOFDAY的属性值(如'First Light'、'Morning')作为对象键,两者类型不匹配。TypeScript认为你未提供Record要求的属性名键,反而使用了宽泛的字符串索引,因此报错。

修复方案

有两种方案可根据需求选择:

方案一:让Record的键匹配TIMEOFDAY的属性值

如果想保持用TIMEOFDAY.FirstLight这类属性值作为对象键,需先固定TIMEOFDAY的类型为字面量类型,再调整Record的键类型:

  1. 给TIMEOFDAY添加as const,让TypeScript保留属性值的字面量类型(默认会推断为string):
export const TIMEOFDAY = {
    FirstLight: 'First Light',
    Morning: 'Morning',
    Antemeridiem: 'Antemeridiem',
    Zenith: 'Zenith',
    Postmeridiem: 'Postmeridiem',
    Evening: 'Evening',
    LastLight: 'Last Light',
    Night: 'Night',
} as const;
  1. 修改TimeOfDayDataRecord的键类型为TIMEOFDAY所有属性值的联合类型:
type TimeOfDayDataRecord = Record<typeof TIMEOFDAY[keyof typeof TIMEOFDAY], TimeOfDayData>

此时TIMEOFDAYDATA的定义即可符合类型要求,不再报错。

方案二:改用TIMEOFDAY的属性名作为对象键

如果希望对象键为FirstLight而非'First Light',直接修改TIMEOFDAYDATA的键写法:

const TIMEOFDAYDATA: TimeOfDayDataRecord = {
    FirstLight: { phase: 1, temperature: 10, hours: 5, lux: 1 },
    Morning: { phase: 2, temperature: 23, hours: 8, lux: 100 },
    Antemeridiem: { phase: 3, temperature: 42, hours: 13, lux: 300 },
    Zenith: { phase: 4, temperature: 55, hours: 16, lux: 500 },
    Postmeridiem: { phase: 3, temperature: 48, hours: 22, lux: 300 },
    Evening: { phase: 2, temperature: 32, hours: 25, lux: 100 },
    LastLight: { phase: 1, temperature: 15, hours: 30, lux: 1 },
    Night: { phase: 0, temperature: -10, hours: 33, lux: 0 },
}

这样就能完美匹配Record<keyof typeof TIMEOFDAY, TimeOfDayData>的类型要求。

内容的提问来源于stack exchange,提问作者All Bits Equal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 16:42:24