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,
AandB, as generic parameters. - The type must return a number type representing the remainder of the division.
Bmust not be zero. IfBis zero, the type should never resolve (i.e., result in a compile-time error).- The result should be non-negative. If
Ais negative, the result should still be a non-negative remainder.
Expected Behavior:
Modulo<10, 3>should resolve to1.Modulo<15, 5>should resolve to0.Modulo<7, 2>should resolve to1.Modulo<-10, 3>should resolve to2.Modulo<10, -3>should resolve to1.Modulo<10, 0>should result in a compile-time error.
Edge Cases to Consider:
- Negative numbers for
A. - Negative numbers for
B. Bbeing zero.- Large numbers for
AandB(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
AandBmust be number types.Bcannot be zero. The type system should prevent usage withB = 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.