I’m trying to construct a type that ensures that everything registered in a requiredFields
array is set within defaults
.
I want defaults
to throw type errors if it is missing any of the requiredFields
’ names, and if its value doesn’t align to the options
for the corresponding item.
requiredFields
is meant to be flexible. The entire object will be known statically—not evaluated at runtime, but I want to configure several different versions with the same overall type-logic that ensures I don’t miss registering defaults
.
const configuration: FormConfiguration = {
defaults: { // should throw error for not having `numbers`
letters: 'f', // should throw error because 'f' isn't an option
},
requiredFields: [
{
name: 'letters',
options: ['a', 'b', 'c'],
},
{
name: 'numbers',
options: [1, 2, 3],
},
],
}
I know I could construct defaults for form items in other ways, but this is merely an example for a much more complex type I’m attempting to create.
This is my attempt at creating types:
type Names = FormConfiguration['requiredFields'][number]['name']
// returning:
// type Names = string
type Options =
FormConfiguration['requiredFields'][number]['options'][number]
// returning:
// type Options = string | number
type FormConfiguration = {
requiredFields: Array<{
name: string
options: (string | number)[]
}>
defaults: Record<Names, Options>
}
Clearly, based on the output, there’s no sense of self-referencing happening, nor an ability to get correct options per item.
This is doable somehow, right?