Open In App

How to Infer First Element of a Tuple as a Tuple Type ?

Last Updated : 24 Apr, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Tuples can be represented as arrays or objects in TypeScript. This will be achieved by knowing Typescript’s type system and methods such as manual inference as well as the use of the advanced type system of TypeScript.

Defining a tuple type in TypeScript resembles the array syntax with the possibility to specify the type for each element position.

Using TypeScript native tuple support

Tuple type is simpler to infer by adding native support for them in TypeScript. Developers can define tuple types explicitly and enjoy TypeScript’s type inference feature that will infer the type of the first element as a tuple. This approach provides strong typing and increases code maintainability.

Syntax:

// Define a tuple type
type MyTuple = [string, number, boolean];
// Infer the first element as a tuple
type FirstElementAsTuple = MyTuple extends [infer First, ...infer Rest] ? [First] : never;

Example: To infer the first element of type as tuple type using native tuple support.

Javascript
// Define a tuple type
type MyTuple = [string, number, boolean];

// Infer the first element as a tuple
type FirstElementAsTuple = 
    MyTuple extends [infer First, ...infer Rest] ? [First] : never;

// Usage
const tuple: MyTuple = ['hello', 42, true];

// firstElement has type [string]
const firstElement: FirstElementAsTuple = [tuple[0]]; 

// Output
console.log("TypeScript Output:");
console.log("Tuple:", tuple);
console.log("First Element as Tuple:", firstElement);

Output:

Tuple: [ 'hello', 42, true ] First Element as Tuple: [ 'hello' ]

In the TypeScript approach, we leverage TypeScript’s type system to create a tuple type (MyTuple) and then employ conditional types to deduce the type of the first element as a tuple (FirstElementAsTuple).

Conditional type using infer

Conditional types in TypeScript allow for creating types that depend on a condition. We can leverage the infer keyword within conditional types to extract and manipulate types within conditional type expressions. Let’s see how we can infer tuple types using conditional types.

Syntax:

type TupleType<T> = T extends [infer First, ...infer Rest] ? [First, ...Rest] : never;

Example: To infer the first element of a tuple as tuple type using infer with conditional type.

Javascript
// Define a conditional type to infer tuple type
type TupleType<T> = 
    T extends [infer First, ...infer Rest] ? [First, ...Rest] : never;

// Test the conditional type
type MyTuple = TupleType<[number, string, boolean]>;

// MyTuple should be [number, string, boolean]
const myTuple: MyTuple = [10, 'hello', true];

console.log(myTuple);

Output:

[10, "hello", true]

The code leverages the infer keyword within a conditional type to infer tuple types based on certain conditions. It specifies a condition type TupleType, which extracts the type of the first element from a tuple type and shows its application by obtaining a tuple type for a tuple.

Mapped Types

Mapped types in TypeScript allow for creating new types by transforming the properties of existing types. We can leverage mapped types to enforce type constraints and perform type inference on tuples. Let’s see how we can use mapped types for this purpose.

Syntax:

type EnforceTuple<T> = {
    [K in keyof T]: K extends number ? T[K] : never;
};

Example: To infer the first element of a tuple as tuple type using mapped type.

Javascript
// Define a mapped type to enforce tuple type
type EnforceTuple<T> = {
    [K in keyof T]: K extends number ? T[K] : never;
};

// Test the mapped type
type MyTuple = EnforceTuple<[number, string, boolean]>;

// MyTuple should be [number, string, boolean]
const myTuple: MyTuple = [10, 'hello', true];

console.log(myTuple);

Output:

[10, "hello", true]

Manual Inference to Extract First Element as Tuple Type

Manual inference provides another approach to extract the first element of a tuple as a tuple type. This method involves explicitly defining the type of the first element while leaving the rest of the tuple elements inferred by TypeScript’s type system.

Syntax:

type FirstElementAsTuple<T extends any[]> = [T[0]]; // Extracts the type of the first element

Example: To infer the first element of type as tuple type using manual inference.

JavaScript
// Define a tuple type
type MyTuple = [string, number, boolean];

// Extract the first element as tuple type manually
type FirstElementAsTuple<T extends any[]> = [T[0]];

// Usage
const tuple: MyTuple = ['hello', 42, true];

// firstElement has type [string]
const firstElement: FirstElementAsTuple<MyTuple> = [tuple[0]];

// Output
console.log("TypeScript Output:");
console.log("Tuple:", tuple);
console.log("First Element as Tuple:", firstElement);

Output:

"TypeScript Output:" 
"Tuple:",  ["hello", 42, true] 
"First Element as Tuple:",  ["hello"] 


Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads