最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to conditionally set a TypeScript property based on another nested property? - Stack Overflow

programmeradmin0浏览0评论

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 user29096361user29096361
Add a comment  | 

2 Answers 2

Reset to default 1

Just 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
};
发布评论

评论列表(0)

  1. 暂无评论