typescript - 如何从另一条记录的记录中选择
问题描述
我确实有像这样组合的常量和记录类型
const PageType = [
'type1',
'type2',
'type3'
] as const;
export type PageType = typeof PageType[number];
interface PageInfo {
title: string
}
interface DetailsInfo {
bla: string;
}
export const Pages: Record<PageType, PageInfo> = {
type1: {
title: 't1'
},
type2: {
title: 't2'
},
type3: {
title: 't3'
}
}
export const Details: Record<PageType, DetailsInfo> = {
type1: {
bla: 'bla1',
},
type2: {
bla: 'bla2',
},
type3: {
bla: 'bla2',
},
};
我想要的是能够做这样的事情Pages[Details.type1].title
<-- 返回编译器错误
基本上通过提供一个Details.type1
类似的电流Datails["type1"]
(字符串PageType
在那里是动态的)我想得到一个相关的Pages.type1
有任何想法吗?
解决方案
这是我认为您正在尝试实现的参考代码,并且显示了编译器错误。当我第一次阅读您的代码时,我对实例变量的大写名称感到非常困惑,就好像它们是类型一样,所以我已经纠正了这一点。
由于类型擦除,无法理解 DetailsInfo 与其查找键分离后来自哪个条目(如我的示例中的函数定义中所暗示的那样)。如果您希望使用它来控制 javascript 逻辑(例如,使用它来查找和检索某些内容),您需要在运行时保留与任何调用或数据项关联的 PageType 键的信息(即作为 javascript 中的显式值)。
const PAGE_TYPE = [
'type1',
'type2',
'type3'
] as const;
export type PageType = typeof PAGE_TYPE[number];
interface PageInfo {
title: string
}
interface DetailsInfo {
bla: string;
}
export const pages: Record<PageType, PageInfo> = {
type1: {
title: 't1'
},
type2: {
title: 't2'
},
type3: {
title: 't3'
}
}
export const details: Record<PageType, DetailsInfo> = {
type1: {
bla: 'bla1',
},
type2: {
bla: 'bla2',
},
type3: {
bla: 'bla2',
},
};
function getPageInfo(detailsInfo:DetailsInfo): PageInfo{
//there is a compiler error here and no known way to implement this function so it returns the 'correct' PageInfo
}
const pageInfo = getPageInfo(details["type1"]);
相比之下,这里是一个可以工作的实现,但您可以看到 PageType 值必须在运行时保留,您希望可以进行查找。我不知道这是否是您实际案例的正确方法,但它表明原始方法缺少什么。
const PAGE_TYPE = [
'type1',
'type2',
'type3'
] as const;
export type PageType = typeof PAGE_TYPE[number];
interface PageInfo<Kind extends PageType> {
title: string
kind:Kind
}
interface DetailsInfo<Kind extends PageType> {
bla: string;
kind:Kind
}
type PageLookup = {
[K in PageType]: PageInfo<K>
}
type DetailsLookup = {
[K in PageType]: DetailsInfo<K>
}
export const pages: PageLookup = {
type1: {
kind:"type1",
title: 't1'
},
type2: {
kind:"type2",
title: 't2'
},
type3: {
kind:"type3",
title: 't3'
}
} as const;
export const details: DetailsLookup = {
type1: {
kind:"type1",
bla: 'bla1',
},
type2: {
kind:"type2",
bla: 'bla2',
},
type3: {
kind:"type3",
bla: 'bla2',
},
} as const;
function getPageTitle<Kind extends PageType>(detailsInfo:DetailsInfo<Kind>): string{
return pages[detailsInfo.kind].title
}
const pageTitle = getPageTitle(details["type1"]);
推荐阅读
- c# - 数据网格视图之外的标签未在数据网格行选定索引 ASP.NET 上更新
- css - 相对于视口的 SVG 背景图像
- assembly - 检查一个键是否被按下并读取它是哪个键的中断
- html - 如何判断给 img 一个固定的、始终可见的位置、填满屏幕并且没有溢出?(没有背景元素))
- google-chrome - 有没有办法在浏览器中缓存媒体文件?
- python - 如何使用多索引数据框绘制多个图形
- java - 使用此代码时 onclicklistener 不起作用
- c# - 线程方法参数不是线程安全的
- html - 整个 div 颜色并且在悬停时不会改变
- bash - bash 中的“FOO= myprogram”如何使“if(getent("FOO"))”在 C 中返回 true?