I have the following types:
type Settings = {
enableAdvancedFeature?: boolean;
};
type Options = {
settings?: Settings;
enforceAdvancedOrder?: boolean;
};
I want to make the enforceAdvancedOrder
property a boolean only when settings.enableAdvancedFeature
is true
.
If settings.enableAdvancedFeature
is false
or undefined
, then enforceAdvancedOrder
should be undefined
.
Here’s an example of the desired behavior:
const validOption1: Options = {
settings: { enableAdvancedFeature: true },
enforceAdvancedOrder: true,
};
const validOption2: Options = {
settings: { enableAdvancedFeature: false },
enforceAdvancedOrder: undefined, // enforceAdvancedOrder should be undefined
};
const invalidOption: Options = {
settings: { enableAdvancedFeature: false },
enforceAdvancedOrder: true, // This should cause a TypeScript error
};
I tried defining a conditional type for Options but couldn’t figure out how to enforce this dependency between the nested properties.
How can I define the Options type to achieve this behavior while keeping it type-safe? Any suggestions would be greatly appreciated!
I have the following types:
type Settings = {
enableAdvancedFeature?: boolean;
};
type Options = {
settings?: Settings;
enforceAdvancedOrder?: boolean;
};
I want to make the enforceAdvancedOrder
property a boolean only when settings.enableAdvancedFeature
is true
.
If settings.enableAdvancedFeature
is false
or undefined
, then enforceAdvancedOrder
should be undefined
.
Here’s an example of the desired behavior:
const validOption1: Options = {
settings: { enableAdvancedFeature: true },
enforceAdvancedOrder: true,
};
const validOption2: Options = {
settings: { enableAdvancedFeature: false },
enforceAdvancedOrder: undefined, // enforceAdvancedOrder should be undefined
};
const invalidOption: Options = {
settings: { enableAdvancedFeature: false },
enforceAdvancedOrder: true, // This should cause a TypeScript error
};
I tried defining a conditional type for Options but couldn’t figure out how to enforce this dependency between the nested properties.
How can I define the Options type to achieve this behavior while keeping it type-safe? Any suggestions would be greatly appreciated!
Share Improve this question asked Jan 19 at 11:41 user29096361user290963612 Answers
Reset to default 1Just like that
type ConditionalOption =
| { enforceAdvancedOrder?: boolean, settings?: { enableAdvancedFeature?: true } }
| { enforceAdvancedOrder?: undefined, settings?: { enableAdvancedFeature?: false | undefined } }
examples
let a: ConditionalOption = {
settings: {
enableAdvancedFeature: true
},
enforceAdvancedOrder: true
} // okay
let b: ConditionalOption = {
settings: {
enableAdvancedFeature: false
},
enforceAdvancedOrder: true
} // throws error
let c: ConditionalOption = {
settings: {
enableAdvancedFeature: false
},
enforceAdvancedOrder: undefined
} // okay
You can use a union type that allows enforceAdvancedOrder
to be a boolean if enableAdvancedFeatures
is set to true
and otherwise requires that enforceAdvancedOrder
is undefined.
Here's how:
type Options = ({
settings?: Settings<true>;
enforceAdvancedOrder?: boolean;
} | {
settings?: Settings<false | undefined>;
enforceAdvancedOrder?: never;
});
type Settings<B extends boolean | undefined = boolean> = B extends undefined ? {
enableAdvancedFeature?: B;
} : {
enableAdvancedFeature: B;
};
Here are some samples to verify:
const validOption1: Options = {
settings: { enableAdvancedFeature: true },
enforceAdvancedOrder: true,
};
const validOption2: Options = {
settings: { enableAdvancedFeature: false },
enforceAdvancedOrder: undefined, // enforceAdvancedOrder should be undefined
};
const validOption3: Options = {
settings: {},
enforceAdvancedOrder: undefined, // enforceAdvancedOrder should be undefined
};
const invalidOption: Options = {
settings: { enableAdvancedFeature: false },
enforceAdvancedOrder: true, // This should cause a TypeScript error
};
const invalidOption2: Options = {
settings: {},
enforceAdvancedOrder: true, // This should cause a TypeScript error
};