Hone logo
Hone
Problems

Type-Level Booleans in TypeScript

In TypeScript, we often need to perform conditional logic at compile time. This is particularly useful for creating highly expressive and type-safe utility types. This challenge focuses on building fundamental type-level boolean logic using TypeScript's powerful conditional types. Understanding these concepts is crucial for advanced type manipulation and creating robust type systems.

Problem Description

Your task is to implement a set of type-level boolean operations in TypeScript. You will define three primitive types representing True and False, and then implement logical operations such as And, Or, and Not that operate on these types.

Requirements:

  1. Primitive Types: Define two distinct types, True and False, to represent boolean values at the type level. These should be distinct enough to be differentiated using conditional types.
  2. Logical NOT (Not<B>): Implement a generic type Not<B> that takes a boolean type B and returns its logical negation.
    • Not<True> should resolve to False.
    • Not<False> should resolve to True.
  3. Logical AND (And<A, B>): Implement a generic type And<A, B> that takes two boolean types A and B and returns their logical conjunction.
    • And<True, True> should resolve to True.
    • And<True, False> should resolve to False.
    • And<False, True> should resolve to False.
    • And<False, False> should resolve to False.
  4. Logical OR (Or<A, B>): Implement a generic type Or<A, B> that takes two boolean types A and B and returns their logical disjunction.
    • Or<True, True> should resolve to True.
    • Or<True, False> should resolve to True.
    • Or<False, True> should resolve to True.
    • Or<False, False> should resolve to False.

Expected Behavior:

When these types are used in TypeScript code, the compiler should correctly infer the resulting boolean type based on the input types and the defined logical operations.

Edge Cases:

  • Ensure your implementations handle all combinations of True and False inputs correctly.
  • Consider how you will differentiate True and False at the type level.

Examples

Example 1: Not Operation

// Assuming True and False are defined and Not<B> is implemented

type NotTrueResult = Not<True>;
// Expected: False

type NotFalseResult = Not<False>;
// Expected: True

Explanation: Not<True> should return False, and Not<False> should return True.

Example 2: And Operation

// Assuming True and False are defined and And<A, B> is implemented

type AndTrueTrue = And<True, True>;
// Expected: True

type AndTrueFalse = And<True, False>;
// Expected: False

type AndFalseTrue = And<False, True>;
// Expected: False

type AndFalseFalse = And<False, False>;
// Expected: False

Explanation: The And operation follows standard boolean logic where the result is True only if both inputs are True.

Example 3: Or Operation

// Assuming True and False are defined and Or<A, B> is implemented

type OrTrueTrue = Or<True, True>;
// Expected: True

type OrTrueFalse = Or<True, False>;
// Expected: True

type OrFalseTrue = Or<False, True>;
// Expected: True

type OrFalseFalse = Or<False, False>;
// Expected: False

Explanation: The Or operation follows standard boolean logic where the result is False only if both inputs are False.

Constraints

  • Your solution must use only TypeScript's built-in type system. No runtime JavaScript code is involved.
  • The primitive True and False types should be defined using interfaces or type aliases.
  • The logical operations (Not, And, Or) must be implemented as generic conditional types.
  • The solution should be concise and idiomatic TypeScript.

Notes

  • A common approach for defining primitive types like True and False is to use literal types (e.g., true and false as type parameters, or dedicated interface markers). Think about how you can leverage conditional types to differentiate between them.
  • Consider how the extends keyword in conditional types can be used to check the "value" of your type-level booleans.
  • You can build more complex logic by combining these basic operations. For instance, XOR can be implemented using Or and And.
Loading editor...
typescript