Hone logo
Hone
Problems

Type-Level Modulo in TypeScript

This challenge asks you to implement a type-level computation in TypeScript to determine the remainder of a division operation between two numbers, at compile time. This is useful for scenarios where you need to perform static analysis, generate code based on numerical properties, or enforce constraints that depend on divisibility.

Problem Description

Your task is to create a TypeScript type, let's call it Modulo<Dividend, Divisor>, that takes two literal number types as input: Dividend and Divisor. The type should resolve to the remainder of Dividend divided by Divisor.

Key Requirements:

  1. Type-Level Computation: The modulo operation must be performed entirely at the TypeScript compile-time using conditional types and recursive type instantiation.
  2. Literal Number Types: The Dividend and Divisor arguments will be constrained to be literal number types (e.g., 3, 10, 0).
  3. Positive Integers: Assume Dividend and Divisor are non-negative integers.

Expected Behavior:

  • Modulo<10, 3> should resolve to 1.
  • Modulo<15, 5> should resolve to 0.
  • Modulo<7, 2> should resolve to 1.

Edge Cases to Consider:

  • Division by Zero: What should happen if Divisor is 0? You should handle this gracefully, perhaps by resolving to a specific error type or a predefined value.
  • Dividend less than Divisor: The modulo of a number smaller than the divisor is the number itself. For example, Modulo<3, 5> should resolve to 3.

Examples

Example 1:

type Result = Modulo<10, 3>;
// Expected: Result should be the type `1`

Explanation: 10 divided by 3 is 3 with a remainder of 1.

Example 2:

type Result = Modulo<15, 5>;
// Expected: Result should be the type `0`

Explanation: 15 divided by 5 is 3 with a remainder of 0.

Example 3:

type Result = Modulo<3, 5>;
// Expected: Result should be the type `3`

Explanation: 3 divided by 5 is 0 with a remainder of 3.

Example 4 (Edge Case):

type Result = Modulo<10, 0>;
// Expected: Result should be an error type or a predefined error indicator

Explanation: Division by zero is undefined. The type should reflect this impossibility.

Constraints

  • Dividend and Divisor will be literal types representing non-negative integers.
  • The Divisor will not exceed a reasonable compile-time limit (e.g., 1000). This is to prevent excessively long compile times due to deep recursion.
  • Your solution must use only standard TypeScript conditional types and recursive type instantiation. No external libraries or compiler flags are allowed.

Notes

This problem is an exercise in advanced type-level programming. You'll likely need to employ recursion and pattern matching on numeric literal types. Consider how you can simulate subtraction and comparison at the type level to implement the modulo logic. A common strategy for type-level arithmetic is to decrement numbers iteratively. Think about how you can define a base case and a recursive step for your Modulo type.

Loading editor...
typescript