В TypeScript условные свойства позволяют нам создавать гибкие и типобезопасные интерфейсы, которые адаптируются в зависимости от определенных условий. Это особенно полезно при работе со сложными структурами данных, где определенные свойства должны присутствовать только при определенных обстоятельствах. В этом сообщении блога мы рассмотрим, как использовать условные свойства, на практическом примере с группами вознаграждения.
Сценарий
Представьте, что у нас есть система, которая управляет различными типами вознаграждений. Каждая награда может быть определенного типа, например «ФИНАНСЫ» или «ДОСТАВКА».
В зависимости от типа вознаграждения следует включать или исключать определенные атрибуты. Например, финансовые вознаграждения должны включать финансовые атрибуты, а вознаграждения за доставку должны включать атрибуты доставки. Кроме того, мы хотим гарантировать, что определенные атрибуты будут включены только в зависимости от типа вознаграждения и вознаграждения по условиям.
Определение типов
Во-первых, давайте определим основные типы и интерфейсы, с которыми мы будем работать:
type RewardType = "FINANCE" | "SHIPPING" | "OTHER"; // Example values for RewardType interface ItemConditionAttribute { // Define the properties of ItemConditionAttribute here } interface RewardAttributes { // Define the properties of RewardAttributes here } interface ShippingAttributes { // Define the properties of ShippingAttributes here } interface FinanceAttributes { // Define the properties of FinanceAttributes here } interface RewardGroupBase { groupId: number; rewardType: RewardType; rewardOn: string; itemConditionAttributes: ItemConditionAttribute[]; }
Использование условных типов
Чтобы гарантировать, что financeAttributes включается только в том случае, если rewardType имеет значение FINANCE, а rewardAttributes не включается, когда rewardOn имеет значение "Finance", мы можем использовать условные типы. Вот как мы определяем тип RewardGroup :
type RewardGroup = RewardGroupBase & ( { rewardType: "FINANCE"; rewardOn: "Finance"; financeAttributes: FinanceAttributes; rewardAttributes?: never; shippingAttributes?: never } | { rewardType: "SHIPPING"; rewardOn: Exclude; shippingAttributes: ShippingAttributes; financeAttributes?: never; rewardAttributes: RewardAttributes } | { rewardType: Exclude ; rewardOn: Exclude ; financeAttributes?: never; shippingAttributes?: never; rewardAttributes: RewardAttributes } );
Объяснение
Базовый интерфейс:
RewardGroupBase содержит общие свойства, которые всегда присутствуют независимо от типа вознаграждения.
Условные типы:
Мы используем объединение трех типов для обработки условных свойств.
Если rewardType – «FINANCE», а rewardOn – «Finance», financeAttributes требуется,
и rewardAttributes и shippingAttributes не разрешены.
Если для rewardType установлено значение «SHIPPING», а для rewardOn не установлено значение «Finance», требуется атрибутshippingAttributes, а атрибутыfinanceAttributes не разрешены, но rewardAttributes включаются.
Для любого другого rewardType и rewardOn , отличного от "Finance", rewardAttributes включается, но ни financeAttributes , ни shippingAttributes не включаются.
Пример использования
Вот как вы можете использовать тип RewardGroup на практике:
const financeReward: RewardGroup = { groupId: 1, rewardType: "FINANCE", rewardOn: "Finance", itemConditionAttributes: [ /* properties */ ], financeAttributes: { /* properties */ } }; const shippingReward: RewardGroup = { groupId: 2, rewardType: "SHIPPING", rewardOn: "Delivery", itemConditionAttributes: [ /* properties */ ], shippingAttributes: { /* properties */ }, rewardAttributes: { /* properties */ } }; // This will cause a TypeScript error because financeAttributes is not allowed for rewardType "SHIPPING" const invalidReward: RewardGroup = { groupId: 3, rewardType: "SHIPPING", rewardOn: "Delivery", itemConditionAttributes: [ /* properties */ ], financeAttributes: { /* properties */ } // Error: financeAttributes };
Отказ от ответственности: Все предоставленные ресурсы частично взяты из Интернета. В случае нарушения ваших авторских прав или других прав и интересов, пожалуйста, объясните подробные причины и предоставьте доказательства авторских прав или прав и интересов, а затем отправьте их по электронной почте: [email protected]. Мы сделаем это за вас как можно скорее.
Copyright© 2022 湘ICP备2022001581号-3