Hone logo
Hone
Problems

Type-Level Factorial in TypeScript

This challenge asks you to implement the factorial function at the TypeScript type level. This means you'll be using TypeScript's advanced type system, specifically conditional types and recursion, to compute the factorial of a number without any runtime JavaScript execution. This exercise is a great way to deepen your understanding of TypeScript's type inference and manipulation capabilities.

Problem Description

You need to create a TypeScript type, let's call it Factorial<N>, that takes a non-negative integer N as a type parameter and resolves to the factorial of N as a numeric literal type.

The factorial of a non-negative integer n, denoted by n!, is the product of all positive integers less than or equal to n.

Mathematically:

  • 0! = 1
  • n! = n * (n-1)! for n > 0

Key Requirements:

  • The type Factorial<N> must infer the correct numeric literal type for the factorial of N.
  • The implementation should be purely at the type level; no runtime code should be involved in the calculation.
  • The type should handle the base case 0! correctly.

Expected Behavior:

  • Factorial<0> should resolve to 1.
  • Factorial<1> should resolve to 1.
  • Factorial<5> should resolve to 120.

Edge Cases:

  • Consider the input 0.
  • Ensure your recursive type terminates correctly.

Examples

Example 1:

type Result = Factorial<0>;
// Expected type: 1

Explanation: The factorial of 0 is defined as 1.

Example 2:

type Result = Factorial<5>;
// Expected type: 120

Explanation: 5! = 5 * 4 * 3 * 2 * 1 = 120.

Example 3:

type Result = Factorial<3>;
// Expected type: 6

Explanation: 3! = 3 * 2 * 1 = 6.

Constraints

  • The input N will be a non-negative integer literal type (e.g., 0, 1, 5, 10).
  • While TypeScript has limits on recursion depth for type instantiation, aim for a solution that is reasonably efficient for moderate integer values (e.g., up to 10-15).
  • The output type must be a numeric literal type.

Notes

This problem will likely involve:

  • Conditional Types: To check for the base case (N = 0) and handle the recursive step.
  • Recursive Type Aliases: To define the factorial calculation that calls itself with a decremented value.
  • Arithmetic Operations at the Type Level: TypeScript doesn't have direct arithmetic operators. You might need helper types to simulate subtraction and multiplication. Consider how to represent subtraction and multiplication using existing type mechanisms. For instance, creating a tuple of a certain length can represent a number.
Loading editor...
typescript