TypeScript 如何通过同键Record的动态键访问对应成员,解决编译报错
你当前写法报错的核心原因是Details的value类型是DetailsInfo(结构为{bla: string}),并非PageType类型的字符串键,自然不能直接作为Pages的索引使用。以下是3种可行的实现方案:
方案1:调整Details的结构,存储PageType类型的标识
如果你的业务需求是Details中每个条目对应存储页面类型标识,直接修改DetailsInfo和Details的定义即可:
const PageType = [ 'type1', 'type2', 'type3' ] as const; export type PageType = typeof PageType[number]; interface PageInfo { title: string } // 修改DetailsInfo结构,存储类型标识 interface DetailsInfo { pageType: PageType; bla: string; } export const Pages: Record<PageType, PageInfo> = { type1: { title: 't1' }, type2: { title: 't2' }, type3: { title: 't3' } } export const Details: Record<PageType, DetailsInfo> = { type1: { pageType: 'type1', bla: 'bla1', }, type2: { pageType: 'type2', bla: 'bla2', }, type3: { pageType: 'type3', bla: 'bla2', }, }; // 此时调用即可正常推导类型 console.log(Pages[Details.type1.pageType].title)
方案2:对动态字符串做类型断言
如果你拿到的动态键是普通string类型,但你100%确定它属于PageType的枚举值,可以直接用类型断言绕过编译器校验:
const dynamicKey: string = 'type1'; // 断言为PageType类型 console.log(Pages[dynamicKey as PageType].title)
方案3:添加类型守卫实现运行时+编译时双安全
如果不确定动态传入的字符串是否合法,写一个类型守卫函数,既可以让编译器识别类型,也能在运行时避免非法键报错:
function isPageType(key: string): key is PageType { return (PageType as readonly string[]).includes(key); } // 使用示例 const dynamicKey: string = 'type1'; if (isPageType(dynamicKey)) { // 该分支下dynamicKey自动被推导为PageType类型 console.log(Pages[dynamicKey].title) } else { // 处理非法键的逻辑 console.error('非法页面类型') }
内容的提问来源于stack exchange,提问作者Sergino
相关产品推荐
相关产品推荐

