I have an object like this (demo in ts playground):
const sites = {
stack: {url: 'https://stackoverflow.com/'},
google: {url: 'https://www.google.com/'},
azure: {url: 'https://portal.azure.com/'}
} as const
What I'd like to do is create a union type with all the keys that were used, which I can do like this:
type SiteNames = keyof typeof sites; // "stack" | "google" | "azure"
However, I'd also like to add type saftey to the sites
intialization where all of the object values are of a certain type like this (demo in ts playground):
interface ISiteDetails {
url: string;
}
const sites: Record<string, ISiteDetails> = {
stackoverflow: {url: 'https://stackoverflow.com/'},
google: {url: 'https://www.google.com/'},
azure: {url: 'https://portal.azure.com/'}
} as const
This provides some type checking when creating sites
, but also removes the const assertion from the final type, so now SiteNames just resolves to a string:
type SiteNames = keyof typeof sites; // string
Question: Is there any way to have both? Strong typing when creating a Record<any, ISiteDetails
but also the ability to extract all the object keys into a new union type?
Workaround: not as ergonomic, but I could add a final layer of type checking by reassigning site to an exported variable like this (demo in ts playground):
const SitesTyped: Record<SiteNames, ISiteDetails> = sites;