Create a tuple in Typescript without explicitly specifying it

Is it possible to create a tuple in Typescript without using type hinting?

If I try to simply do

const tuple = [1, 2];

the type of tuple becomes number[]

The closest I can come to a one-liner is

const tuple: [number, number] = [1, 2];

Am I overlooking something, or is this the only way?

Answer №1

When working with TypeScript 3.0, you now have the ability to create your own utility function:

const createTuple = <T extends any[]>(...args: T): T => args

You can then utilize this function as follows:

const newTuple = createTuple(1, 2) // newTuple type is [number, number]

Answer №2

Arrays in Typescript do not automatically convert to tuple types. You have the option to explicitly define the type, or you can simplify it by using a helper function that still allows for some inference.

const tuple = <T extends [any] | any[]>(args: T): T => args
tuple(["A", "B"]) // [string, string]

Update

As of version 3.4, you can also utilize an as const assertion. This removes the need for an additional function but restricts the tuple to being read-only:

var t = [1, ''] as const;
t[0] = 1  //err

Starting from version 3.0, tuples can be inferred using rest parameters:

const tuple = <T extends any[]>(...args: T): T => args
tuple("A", "B") // [string, string]

Answer №3

With the release of TypeScript 3.4, you can easily use as const at the end of your code.

const tuple = [1, 2] as const;

Credit goes to @bela53's response, which includes a more comprehensive example and a link to TS playground.

Answer №4

TypeScript 4.0 introduces a new method for implicitly inferring tuple types:

By utilizing the type [...T], where T represents an array-like type parameter, you can conveniently express a preference for the inference of tuple types[:] (documentation)

const tuple = <T extends unknown[]>(args: [...T]): T => args
tuple(["A", "B"]) // [string, string]

Access Playground

Answer №5

I wanted to share this useful tip I discovered about using as const. It's interesting how it creates readonly tuples and how other methods can widen the types of values.

const tuple = <T extends any[]>(xs: readonly [...T]): T => xs as T;

There are 2 ways to use it:

const a = tuple(['foo', 10] as const)

a is now type ["foo", 10], not readonly, andtypeof a[number] is "foo" | 10


const b = tuple(['foo', 10]);

b becomes type [string, number] and typeof b[number] is string | number

Answer №6

It would be best to create a specific type for the tuple in order to make it more descriptive.

type TreeHouse = [location: Location, name: string, capacity: number];

After defining the type, you can use it like this:

<TreeHouse>[new Location(…), "Treeston", 6]

Unfortunately, this tuple literal does not support parameter names.

Remember to be cautious of precedence! <TreeHouse>(…) does not have the same precedence as new TreeHouse(…).

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Exploring the vast world of deep type information in the Typescript JSON

Examine the contents of the file data.json: { "au": { "name": "Australia", "market_id": "111172", "language_code": "en_AU" }, "br": { "nam ...

As time passes, the Azure Service Bus Consumer experiences a decline in performance

My issue involves managing different topics with subscriptions, each tied to a consumer. Over time, I've noticed a decline in the number of messages received. Despite trying to utilize maxconcurrentcalls, it seems to only be effective at the start. My ...

"Although TypeOrm successfully generates the database, there seems to be a connectivity issue

Attempting to set up a JWT authentication system using NestJs and SQLite. The code successfully generates the SQLite file, but then throws an error stating "Unable to connect to the database." Upon checking with the SQLite terminal, it became apparent that ...

From where does useTranslate fetch the translations?

I have started my journey to learn React with NextJS and recently purchased this amazing template. While exploring the src/pages/terms.tsx file, I came across some quite complex code. One thing that intrigued me was the question: What does the ? in conten ...

What is the process for importing a wasm file created with wasm-pack into a TypeScript file?

Here are the steps you need to follow: cargo generate --git https://github.com/rustwasm/wasm-pack-template Specify your project name as: project-name // src/lib.rsj mod utils; use wasm_bindgen::prelude::*; #[cfg(feature ="wee_alloc")] #[globa ...

TS2688 Error: Type definition file for 'tooltip.js' not found

Why am I getting an 'undefined' error when trying to import the Tooltip class from the npm tooltip.js package in my TypeScript file? ...

Modify the property of the ChildComponent by utilizing the ViewChild method

I recently started exploring Angular and I've been experimenting with ViewChild and ViewChildren. In one scenario, I have a property called today = new Date() in my Component2. I'm accessing this property in Component1 using ViewChild and continu ...

Testing Angular Components with Jasmine and Karma: When handling the 'onChange' event, the changeEvent parameter of type MatRadioChange should not be void and must be assigned to a parameter of type

Hey there, I was working on a test for a call where I am using to emit the event: onChange(eventName: MatRadioChange): void { this.eventName.emit(eventName.value); } Here is the test I have written for it: describe('onChange', (eventName: ...

Pointer Cursor in CSS

I am experiencing a strange issue. When I set the cursor attribute value directly as a string like return ( <Grid item> <Card sx={{ padding: "1rem", ":hover": { cursor: "pointer" ...

Unable to bring in an exported class from a TypeScript file

I have a TypeScript file named foo.ts that contains an exported class called "Foo" export default class Foo{ } I am attempting to import this class into another file within the same directory import {Foo} from './foo'; However, I am encounter ...

Ways to prevent an array from being reset

My issue involves the clothes and orders tables, along with an array based on Clothes and Orders models. Whenever I add a clothes element into the Orders array and specifically update the amount and price of the selected item, it also updates the Clothes a ...

"Exploring the methods to retrieve Firebase authentication error details and outputting the console log message along with

When I encounter an error in Firebase authentication, I want to display it in the console log. However, nothing is being logged and the catch block is not even getting executed. I am unsure about why this is happening and how to retrieve the error code and ...

In React-Native, implement a function that updates one state based on changes in another state

I need to trigger a function when a specific state changes. However, I encountered the error 'maximum update depth reached'. This seems illogical as the function should only respond to changes from stateA to update stateB. I attempted using setSt ...

Distinguishing between type assertion of a returned value and defining the return type of a function

What distinguishes between performing a type assertion on a function's return value and explicitly typing the return value in the function signature? Let's consider only simple functions with a single return statement. interface Foo { foo: numbe ...

What are the ways in which I can utilize the private or public keyword in TypeScript?

Having issues specifying private or public properties in my TypeScript files (tsx/ts files) for a React project. The IDE being used is WebStorm 2021.3. TypeScript version in use is 4.5.4. Attempts were made to adjust some properties in the tsconfig.json ...

Tips on improving the efficiency of a nested 'for' loop through functional programming

Looking for a way to optimize my function that checks for repeated cell phone numbers in a list. Currently, I am using nested for loops and wondering how I can implement functional programming instead? checkDuplicate(): boolean { for (let i = 0; ...

What is the best approach to obtain a Generic and static reference to a MongoDB collection?

My goal is to create a generic and static class method called getOne<T>() that can return MongoDB objects as an Item, where the Item can be either a Book or a Film. Initially, I had an idea on how to achieve this, but now I am struggling with dynamic ...

AngularJS, sort through "afoo" excluding "foo"

I am attempting to implement a filter within an ng-repeat Main.HTML <table> <tr ng-repeat="param in MyParam | filter: UnrequestValue"> <td>{{param.Label}}</td> </tr> </table> Main.js MyParam: ...

Understanding the Usage of FormData in NextJS

I'm trying to read fetch's body contents. Here's the code I'm using: fetch('/api/foo', { method: 'POST', body: new FormData(formRef.current), }); https://i.sstatic.net/6YB1V.png Now I need to parse the body dat ...

Is it possible to use TypeScript or Angular to disable or remove arrow key navigation from a PrimeNG Table programmatically?

Is there a way to programmatically prevent left and right arrow key navigation in a PrimeNG Table with cell editing, without the need to modify the Table component source code? You can check out an example here: Angular Primeng Tableedit Demo code. I mana ...