For a project, I am currently developing a function that verifies whether a specific field is required by passing the field's name as an argument. My goal is to ensure that the function only accepts field names that are defined within the Config type and have a corresponding RequiredConfig with a 'required' property set. Initially, I was able to achieve this by setting the function parameter type as ValidationField as shown below:
type Field = 'name' | 'surname' | 'age' | 'height' | 'school';
type ValidationField = Extract<Field, 'name' | 'surname'>;
type RequiredConfig = {required?: boolean};
type ValidationConfig<T> = T extends ValidationField ? RequiredConfig : {};
type Config = {
[K in Field]?: ValidationConfig<K> & {visible?: boolean};
}
const config: Config = {name: {required: true, visible: true}, surname: {required: true, visible: true}, age: {visible: false}}
const checkRequired = (field: ValidationField) => config[field]?.required
However, I am now curious if it is possible to achieve the same functionality without direct access to the ValidationField type, but only through the Config, ValidationConfig, and RequiredConfig types. Is there a way to accomplish this?
const checkRequired = <T extends Field>(field: Config[Field] extends ...? T : never) => config[field]?.required