Hone logo
Hone
Problems

TypeScript: EndsWith Utility Type

In TypeScript, we often need to create types that dynamically adapt based on the properties of other types. This challenge focuses on building a utility type that checks if a given tuple type ends with a specific type. This is useful for type-safe operations on arrays and tuples where you need to ensure a particular type exists at the end of a sequence.

Problem Description

Your task is to create a TypeScript utility type named EndsWith<T, U> where:

  • T is a tuple type.
  • U is a single type.

The EndsWith<T, U> type should resolve to true if the last element of the tuple type T is assignable to the type U. Otherwise, it should resolve to false.

Key Requirements:

  1. The utility type must be named EndsWith.
  2. It must accept two type parameters: T (the tuple) and U (the potential last element type).
  3. It must return a boolean literal type (true or false).
  4. The comparison should check if the type of the last element of T is assignable to U.

Expected Behavior:

  • If T is an empty tuple [], it cannot end with any type U, so EndsWith<[], U> should be false.
  • If the last element of T is assignable to U, the type should resolve to true.
  • If the last element of T is not assignable to U, the type should resolve to false.

Edge Cases:

  • Empty tuple [].
  • Tuple with a single element.
  • Comparing with any and unknown.

Examples

Example 1:

type MyTuple = [string, number, boolean];
type Result = EndsWith<MyTuple, boolean>;
// Expected Output: true

Explanation: The last element of MyTuple is boolean, which is assignable to boolean.

Example 2:

type MyTuple = [string, number, boolean];
type Result = EndsWith<MyTuple, number>;
// Expected Output: false

Explanation: The last element of MyTuple is boolean, which is not assignable to number.

Example 3:

type SingleElementTuple = [string];
type Result = EndsWith<SingleElementTuple, string>;
// Expected Output: true

Explanation: The last element of SingleElementTuple is string, which is assignable to string.

Example 4:

type EmptyTuple = [];
type Result = EndsWith<EmptyTuple, string>;
// Expected Output: false

Explanation: An empty tuple has no last element, so it cannot end with string.

Example 5:

type MixedTuple = [string, number];
type Result = EndsWith<MixedTuple, string | number>;
// Expected Output: true

Explanation: The last element of MixedTuple is number, which is assignable to string | number.

Example 6:

type AnyTuple = [string, any];
type Result = EndsWith<AnyTuple, string>;
// Expected Output: true

Explanation: The last element is any. string is assignable to any.

Example 7:

type UnknownTuple = [string, unknown];
type Result = EndsWith<UnknownTuple, string>;
// Expected Output: true

Explanation: The last element is unknown. string is assignable to unknown.

Constraints

  • The utility type EndsWith must be implemented using only TypeScript's type-level features (conditional types, infer, etc.).
  • No runtime code execution is involved. The solution must be purely a compile-time type.
  • Performance is not a primary concern for this exercise, but the solution should be reasonably efficient for typical tuple lengths.

Notes

To extract the last element of a tuple, you might consider using inference with rest parameters in conditional types. Remember how TypeScript handles tuple types and their elements. Consider how to handle the case of an empty tuple explicitly.

Loading editor...
typescript