Typescript 如何从另一条记录重新记录中进行选择
我确实有常数和记录类型这样组合Typescript 如何从另一条记录重新记录中进行选择,typescript,typescript-generics,typescript2.0,Typescript,Typescript Generics,Typescript2.0,我确实有常数和记录类型这样组合 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
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',
},
};
const页面类型=[
“类型1”,
“类型2”,
“类型3”
]作为常量;
导出类型PageType=页面类型的类型[编号];
界面页面信息{
标题:字符串
}
接口详细信息信息信息{
bla:字符串;
}
导出常量页:记录={
类型1:{
标题:“t1”
},
类型2:{
标题:“t2”
},
类型3:{
标题:“t3”
}
}
导出常量详细信息:记录={
类型1:{
布拉:“布拉1”,
},
类型2:{
布拉:“布拉2”,
},
类型3:{
布拉:“布拉2”,
},
};
我想做的是能够像
Pages[Details.type1].title这样的操作,这是我认为您正在尝试实现的、显示编译器错误的参考代码。当我第一次阅读您的代码时,我对实例变量被赋予大写的名称感到非常困惑,就好像它们是类型一样,所以我已经纠正了这一点
因为在将DetailsInfo从其查找键中分离出来之后,无法理解它来自哪个条目(如我的示例中的函数定义所暗示的)。如果希望使用PageType键控制javascript逻辑(例如,用于查找和检索某些内容),则需要在运行时保留与任何调用或数据项关联的PageType键的信息(即作为javascript中的显式值)
const页面类型=[
“类型1”,
“类型2”,
“类型3”
]作为常量;
导出类型PageType=页面类型\类型[编号];
界面页面信息{
标题:字符串
}
接口详细信息信息信息{
bla:字符串;
}
导出常量页:记录={
类型1:{
标题:“t1”
},
类型2:{
标题:“t2”
},
类型3:{
标题:“t3”
}
}
导出常量详细信息:记录={
类型1:{
布拉:“布拉1”,
},
类型2:{
布拉:“布拉2”,
},
类型3:{
布拉:“布拉2”,
},
};
函数getPageInfo(detailsInfo:detailsInfo):PageInfo{
//这里有一个编译器错误,并且没有实现此函数的已知方法,因此它返回“正确”的PageInfo
}
const pageInfo=getPageInfo(详细信息[“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"]);
const页面类型=[
“类型1”,
“类型2”,
“类型3”
]作为常量;
导出类型PageType=页面类型\类型[编号];
界面页面信息{
标题:字符串
种类:种类
}
接口详细信息信息信息{
bla:字符串;
种类:种类
}
类型PageLookup={
[K in PageType]:页面信息
}
类型DetailsLookup={
[K in PageType]:详细信息信息信息
}
导出常量页面:页面查找={
类型1:{
种类:“类型1”,
标题:“t1”
},
类型2:{
种类:“type2”,
标题:“t2”
},
类型3:{
种类:“type3”,
标题:“t3”
}
}作为常量;
导出常量详细信息:DetailsLookup={
类型1:{
种类:“类型1”,
布拉:“布拉1”,
},
类型2:{
种类:“type2”,
布拉:“布拉2”,
},
类型3:{
种类:“type3”,
布拉:“布拉2”,
},
}作为常量;
函数getPageTitle(detailsInfo:detailsInfo):字符串{
返回页面[detailsInfo.kind]。标题
}
const pageTitle=getPageTitle(详细信息[“type1”]);
getPageInfo
是不是需要实现一些东西?试着填补你原始帖子的空白,这就是你想知道如何实现的功能,对吧?我是说,根据这个定义,没有可能实现。相比之下,如果您有getPageInfo(pageType:pageType,lookup:Record=pages)签名(例如pageType是可访问的实际值)然后你就可以做了。这是否意味着我想要实现的是一个坏主意?不,这只是意味着你需要重新构造你的方法,以确保javascript运行时能够访问你想要用于查找的信息。这不能用你尝试的方式来完成。
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"]);