Say I have an object that looks like this:
const configuration: Config = {
options: {
'Option 1': 'some value here',
'Option 2': 'some other value here'
},
defaultOption: 'Option 1'
}
How can I write the type Config
such that:
defaultOption
can only be one of the keys in the .options
object. ie. 'Option 1'
or 'Option 2'
in the case above..options
can have any number of key-value pairs..options
keys upfront. So, the user shouldn't have to specify const configuration: Config<'Option 1' | 'Option 2'> = ...
. It's ok to use generics, but the user shouldn't have to specify them.In order to do that and validate, you need to infer your config object from function argument:
type Configuration<
Options
>
= {
options: Options,
defaultOption: keyof Options
}
const config = <
Options extends Record<string, string>,
Config extends Configuration<Options>,
Default extends keyof Config['options'],
>(config: { options: Options, defaultOptions: Default }) => config
const result = config({
options: {
'Option 1': 'some value here',
'Option 2': 'some other value here'
},
defaultOptions: 'Option 1'
}) // ok
const result2 = config({
options: {
'Option 1': 'some value here',
'Option 2': 'some other value here'
},
defaultOptions: 'invalid property'
}) // error