Below is a revamped approach to address the issue you are facing in your code snippet, which results in a compiler error. Initially, I found it confusing that the instance variables were given capitalized names resembling types, so I have made corrections accordingly.
Due to type erasure, once a DetailsInfo object loses its lookup key association, it becomes challenging to determine its source entry (as suggested in the function definition within my revised example). To enable JavaScript logic control based on PageType keys for lookup and data retrieval purposes, runtime preservation of this information is crucial (i.e., as an explicitly defined value in the 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{
//the current implementation leads to a compiler error with no apparent solution to return the correct PageInfo
}
const pageInfo = getPageInfo(details["type1"]);
On the contrary, here is an alternative working approach where the PageType value must be preserved at runtime to enable successful lookups. While I cannot guarantee that this aligns perfectly with your real-world scenario, it highlights what was lacking in your initial strategy.
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"]);