Feature Flag Type System in TypeScript
Feature flags (or feature toggles) are a powerful technique for enabling or disabling features in your application without deploying new code. This challenge asks you to define a robust type system in TypeScript to represent different types of feature flags, their states, and how they can be evaluated. This will help ensure type safety and improve code maintainability when working with feature flags.
Problem Description
You need to create a TypeScript type system to represent feature flags. The system should support different flag types (Boolean, Percentage, and Date-based) and their corresponding states. The goal is to define types that enforce correct usage and prevent common errors when evaluating feature flags.
Key Requirements:
- Flag Types: Define types for
BooleanFlag,PercentageFlag, andDateFlag.BooleanFlag: Represents a flag that is either enabled or disabled.PercentageFlag: Represents a flag that is enabled for a certain percentage of users.DateFlag: Represents a flag that is enabled or disabled based on a specific date and time.
- Flag State: Each flag type should have a state associated with it.
BooleanFlag:enabled: booleanPercentageFlag:percentage: number(representing the percentage of users to enable the feature for, between 0 and 100)DateFlag:date: Date(representing the date and time when the flag should be enabled/disabled)
- Flag Evaluation Function Type: Define a type for a function that evaluates a flag based on its type and state. This function should take a flag object and return a boolean indicating whether the feature is enabled.
- Flag Object Type: Create a union type that encompasses all possible flag types. This will allow you to represent a feature flag generically.
Expected Behavior:
The type system should:
- Enforce that
percentageforPercentageFlagis between 0 and 100. - Allow only valid flag types to be assigned to the union type.
- Provide type safety when evaluating flags using the defined evaluation function type.
Edge Cases to Consider:
- Invalid percentage values (outside the 0-100 range).
- Handling of dates in different timezones (consider using UTC).
- How to represent a flag that is disabled indefinitely (for
DateFlag).
Examples
Example 1:
Input:
const booleanFlag: BooleanFlag = { enabled: true };
const percentageFlag: PercentageFlag = { percentage: 50 };
const dateFlag: DateFlag = { date: new Date('2024-01-01T00:00:00Z') };
Output:
// No type errors. The types are correctly defined.
Example 2:
Input:
const invalidPercentageFlag: PercentageFlag = { percentage: 150 }; // Intentionally invalid
Output:
// TypeScript should flag this as a type error because percentage is outside the valid range.
Example 3:
Input:
type FeatureFlag = BooleanFlag | PercentageFlag | DateFlag;
const flag1: FeatureFlag = { enabled: true };
const flag2: FeatureFlag = { percentage: 25 };
const flag3: FeatureFlag = { date: new Date() };
const evaluateFlag = (flag: FeatureFlag): boolean => {
// Implementation details omitted for brevity. The type system should ensure
// that the flag is handled correctly based on its type.
return true;
};
Output:
// No type errors. The `evaluateFlag` function correctly handles different flag types.
Constraints
- The
percentagevalue inPercentageFlagmust be a number between 0 and 100 (inclusive). - All dates should be represented in UTC to avoid timezone issues.
- The solution should be written in TypeScript and adhere to good coding practices.
- The solution should be well-documented and easy to understand.
Notes
- Consider using discriminated unions to make it easier to determine the type of a flag at runtime.
- You don't need to implement the actual flag evaluation logic within the
evaluateFlagfunction; focus on defining the types correctly. - Think about how you might extend this type system to support other flag types in the future.
- The goal is to create a type-safe system, not a runtime system. TypeScript's type checking is your primary tool.