Hone logo
Hone
Problems

Type-Level Factorial in TypeScript

Calculating factorials is a fundamental mathematical operation. This challenge asks you to implement a factorial function at the type level in TypeScript, meaning the factorial calculation happens during compile time using TypeScript's advanced type system. This demonstrates a powerful technique for performing computations and generating complex types based on input types.

Problem Description

You need to create a type Factorial that takes a number type N (represented as a type) and calculates its factorial, also as a type. The factorial of a non-negative integer N is the product of all positive integers less than or equal to N. The type Factorial<N> should represent the result of this calculation.

Key Requirements:

  • The solution must be implemented using TypeScript's type system, leveraging conditional types and recursion.
  • The factorial calculation must be performed at compile time.
  • The type Factorial<N> should be a union of number types representing the factorial.
  • The solution should handle the base case of Factorial<0> correctly.

Expected Behavior:

  • Factorial<0> should resolve to 1.
  • Factorial<1> should resolve to 1.
  • Factorial<2> should resolve to 2.
  • Factorial<3> should resolve to 6.
  • Factorial<4> should resolve to 24.
  • And so on...

Edge Cases to Consider:

  • The input N is assumed to be a non-negative integer represented as a type. While TypeScript doesn't inherently enforce this, the type system should behave as expected for such inputs. Negative numbers are not part of the factorial definition.

Examples

Example 1:

Input: Factorial<0>
Output: 1
Explanation: The factorial of 0 is defined as 1.

Example 2:

Input: Factorial<3>
Output: 6
Explanation: 3! = 3 * 2 * 1 = 6.

Example 3:

Input: Factorial<4>
Output: 24
Explanation: 4! = 4 * 3 * 2 * 1 = 24.

Constraints

  • The solution must be purely type-level; no runtime calculations are allowed.
  • The solution should be reasonably efficient in terms of type complexity. Excessively complex type manipulations can lead to compilation errors or performance issues.
  • The input type N is assumed to be a number-like type.

Notes

  • Consider using conditional types (infer, extends) to implement the recursive logic.
  • Think about how to represent the factorial as a union of number types. You might need to use distributive conditional types to achieve this.
  • The base case (factorial of 0) is crucial for terminating the recursion.
  • This problem is a good exercise in understanding TypeScript's advanced type system and its capabilities for compile-time computations.
Loading editor...
typescript