Hone logo
Hone
Problems

Type-Level Modulo Operation in TypeScript

Type-level programming allows us to perform computations at compile time, enabling powerful type transformations and validations. Implementing a modulo operation at the type level can be useful for tasks like ensuring array sizes are multiples of a certain value, or for creating type-safe pagination logic. This challenge asks you to create a TypeScript type that calculates the modulo of two numbers at compile time.

Problem Description

You need to implement a type Modulo<A extends number, B extends number> that calculates the modulo of A divided by B. The result should also be a number type. The modulo operation should adhere to the standard mathematical definition: A % B.

Key Requirements:

  • The type must accept two number types, A and B, as generic parameters.
  • The type must return a number type representing the remainder of the division.
  • B must not be zero. If B is zero, the type should never resolve (i.e., result in a compile-time error).
  • The result should be non-negative. If A is negative, the result should still be a non-negative remainder.

Expected Behavior:

  • Modulo<10, 3> should resolve to 1.
  • Modulo<15, 5> should resolve to 0.
  • Modulo<7, 2> should resolve to 1.
  • Modulo<-10, 3> should resolve to 2.
  • Modulo<10, -3> should resolve to 1.
  • Modulo<10, 0> should result in a compile-time error.

Edge Cases to Consider:

  • Negative numbers for A.
  • Negative numbers for B.
  • B being zero.
  • Large numbers for A and B (though performance isn't a primary concern for this type-level challenge).

Examples

Example 1:

Input: Modulo<10, 3>
Output: 1
Explanation: 10 divided by 3 is 3 with a remainder of 1.

Example 2:

Input: Modulo<15, 5>
Output: 0
Explanation: 15 divided by 5 is 3 with a remainder of 0.

Example 3:

Input: Modulo<-10, 3>
Output: 2
Explanation: -10 divided by 3 is -4 with a remainder of 2.

Example 4:

Input: Modulo<10, 0>
Output:  (Compile-time error)
Explanation: Division by zero is undefined.

Constraints

  • A and B must be number types.
  • B cannot be zero. The type system should prevent usage with B = 0.
  • The result must be a non-negative number type.
  • The solution should be reasonably efficient in terms of TypeScript type complexity (avoiding excessively complex recursion if possible).

Notes

Consider using conditional types and potentially distributive conditional types to achieve the desired behavior. Think about how to handle negative numbers correctly to ensure a non-negative remainder. You might find it helpful to break down the problem into smaller, more manageable type-level functions. Remember that TypeScript's type system is based on inference, so your type should be able to infer the correct result based on the input types.

Loading editor...
typescript