Reputation: 1327
I have an object in a project that I'm trying to type:
export const dateFormat = {
hourOnly: { hour: 'numeric' }
…
}
I know that the values in this object should fit Intl.DateTimeFormatOptions
so I tried:
export const dateFormat: {[key: string]: Intl.DateTimeFormatOptions} = {
hourOnly: { hour: 'numeric' }
…
}
This works but I lose the ability to get auto complete for this object elsewhere in the project. I tried adding as const
at the end, but that didn't help.
Is there a way to enforce an objects values while still getting auto-complete for the keys?
I also tried:
type dateFormatOptions = 'hourOnly'
export const dateFormat: {[key: dateFormatOptions]: Intl.DateTimeFormatOptions} = {
hourOnly: { hour: 'numeric' }
…
}
but in this case typescript says the index signature should be a string or a number?
Upvotes: 0
Views: 44
Reputation: 250336
If you know the keys you can just use Record
to create a type that has those explicit keys of the type you want (Record
is called a mapped type)
type dateFormatOptions = 'hourOnly'
export const dateFormat: Record<dateFormatOptions, Intl.DateTimeFormatOptions> = {
hourOnly: { hour: 'numeric' }
}
This does require you to keep the names of the properties in two places. Another option is to use a function with a constrained generic type parameter. The type parameter constraint will keep all values of the specified type but the actual keys will be inferred based on the object you pass in.
function createDateFormatOptions<K extends PropertyKey>(o: Record<K, Intl.DateTimeFormatOptions>): Record<K, Intl.DateTimeFormatOptions> {
return o;
}
export const dateFormat = createDateFormatOptions({
hourOnly: { hour: 'numeric' },
})
Upvotes: 1