Hone logo
Hone
Problems

Implementing Sized Types in TypeScript

Sized types in TypeScript allow you to enforce that a type has a known size in bytes. This is particularly useful when interacting with low-level APIs, working with memory management, or ensuring data structures conform to specific size constraints. This challenge asks you to create a utility type that determines the size of a TypeScript type in bytes and then use that to create a new type that enforces a maximum size.

Problem Description

You need to implement two utility types: sizeOf<T> and MaxSize<T, MaxSizeInBytes>.

  • sizeOf<T>: This type should take a TypeScript type T as input and return a number representing the size of that type in bytes. You'll need to handle various primitive types (number, string, boolean, etc.) and basic composite types (arrays, tuples, objects). For simplicity, assume the following sizes:

    • number: 8 bytes
    • string: 8 bytes (regardless of actual string length)
    • boolean: 1 byte
    • Array<T>: 4 bytes (pointer size) + sizeOf<T> * length (assume length is known at compile time and is a number)
    • Tuple<T1, T2, ...>: sizeOf<T1> + sizeOf<T2> + ...
    • object: 8 bytes (pointer size) - For objects, assume all properties are of type number and have a size of 8 bytes. The number of properties is assumed to be known at compile time and is a number.
    • Other types: 0 (unsupported - this is acceptable for this challenge)
  • MaxSize<T, MaxSizeInBytes>: This type should take a TypeScript type T and a number MaxSizeInBytes as input. It should return T if the size of T (calculated using sizeOf<T>) is less than or equal to MaxSizeInBytes. Otherwise, it should return never.

Examples

Example 1:

Input:
type MyType = number;

Output:
type Result1 = MaxSize<MyType, 8>; // Result1 is number

Explanation: sizeOf<number> is 8, which is <= 8.

Example 2:

Input:
type MyType = number[];

Output:
type Result2 = MaxSize<MyType, 16>; // Result2 is never

Explanation: sizeOf<number[]> is 4 + 8 * length. If length is 1, size is 12. If length is 2, size is 20.  Since 20 > 16, the result is never.

Example 3:

Input:
type MyType = [number, boolean];

Output:
type Result3 = MaxSize<MyType, 10>; // Result3 is [number, boolean]

Explanation: sizeOf<[number, boolean]> is 8 + 1 = 9, which is <= 10.

Example 4:

Input:
type MyObject = { a: number, b: number };

Output:
type Result4 = MaxSize<MyObject, 24>; // Result4 is MyObject

Explanation: sizeOf<MyObject> is 8 + 8 + 8 = 24, which is <= 24.

Constraints

  • MaxSizeInBytes must be a number.
  • The length of arrays and the number of properties in objects must be known at compile time (i.e., they must be literal types or numbers).
  • The sizes of primitive types are fixed as defined above.
  • The solution must be written in TypeScript.
  • The solution should be type-safe and avoid runtime errors.

Notes

  • This challenge focuses on type-level calculations. No runtime execution is required.
  • Consider using conditional types and recursive types to implement sizeOf<T>.
  • The object type size calculation is a simplification. In a real-world scenario, you would need to recursively calculate the size of each property.
  • The string type size is also a simplification. The actual size depends on the encoding and length of the string.
  • Error handling for unsupported types is not required; returning 0 is acceptable.
  • Focus on correctness and type safety. Performance is not a primary concern.
Loading editor...
typescript