Skip to content

Exploring the Power of Square Brackets in TypeScript

Published: at 

Introduction

TypeScript, the popular statically-typed superset of JavaScript, offers advanced type manipulation features that enhance development with strong typing. Square brackets [] serve distinct purposes in TypeScript. This post details how square brackets work in TypeScript, from array types to indexed access types and beyond.

1. Defining Array Types

Square brackets in TypeScript define array types with precision.

let let numbers: number[]numbers: number[] = [1, 2, 3];
let let strings: string[]strings: interface Array<T>Array<string> = ["hello", "world"];

This syntax specifies that numbers contains numbers, and strings contains strings.

2. Tuple Types

Square brackets define tuples - arrays with fixed lengths and specific types at each index.

type type Point = [number, number]Point = [number, number];
let let coordinates: Pointcoordinates: type Point = [number, number]Point = [12.34, 56.78];

In this example, Point represents a 2D coordinate as a tuple.

3. The length Property

Every array in TypeScript includes a length property that the type system recognizes.

type type LengthArr<T extends Array<any>> = T["length"]LengthArr<function (type parameter) T in type LengthArr<T extends Array<any>>T extends interface Array<T>Array<any>> = function (type parameter) T in type LengthArr<T extends Array<any>>T["length"];

type 
type foo = 2
foo
= type LengthArr<T extends Array<any>> = T["length"]LengthArr<["1", "2"]>;

TypeScript recognizes length as the numeric size of the array.

4. Indexed Access Types

Square brackets access specific index or property types.

type type Point = [number, number]Point = [number, number];
type 
type FirstElement = number
FirstElement
= type Point = [number, number]Point[0];

Here, FirstElement represents the first element in the Point tuple: number.

5. Creating Union Types from Tuples

Square brackets help create union types from tuples efficiently.

type type Statuses = ["active", "inactive", "pending"]Statuses = ["active", "inactive", "pending"];
type 
type CurrentStatus = "active" | "inactive" | "pending"
CurrentStatus
= type Statuses = ["active", "inactive", "pending"]Statuses[number];

Statuses[number] creates a union from all tuple elements.

6. Generic Array Types and Constraints

Square brackets define generic constraints and types.

function function logArrayElements<T extends any[]>(elements: T): voidlogArrayElements<function (type parameter) T in logArrayElements<T extends any[]>(elements: T): voidT extends any[]>(elements: T extends any[]elements: function (type parameter) T in logArrayElements<T extends any[]>(elements: T): voidT) {
  elements: T extends any[]elements.Array<any>.forEach(callbackfn: (value: any, index: number, array: any[]) => void, thisArg?: any): void
Performs the specified action for each element in an array.
@paramcallbackfn A function that accepts up to three arguments. forEach calls the callbackfn function one time for each element in the array.@paramthisArg An object to which the this keyword can refer in the callbackfn function. If thisArg is omitted, undefined is used as the this value.
forEach
(element: anyelement => var console: Console
The `console` module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers. The module exports two specific components: * A `Console` class with methods such as `console.log()`, `console.error()` and `console.warn()` that can be used to write to any Node.js stream. * A global `console` instance configured to write to [`process.stdout`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstdout) and [`process.stderr`](https://nodejs.org/docs/latest-v22.x/api/process.html#processstderr). The global `console` can be used without importing the `node:console` module. _**Warning**_: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the [`note on process I/O`](https://nodejs.org/docs/latest-v22.x/api/process.html#a-note-on-process-io) for more information. Example using the global `console`: ```js console.log('hello world'); // Prints: hello world, to stdout console.log('hello %s', 'world'); // Prints: hello world, to stdout console.error(new Error('Whoops, something bad happened')); // Prints error message and stack trace to stderr: // Error: Whoops, something bad happened // at [eval]:5:15 // at Script.runInThisContext (node:vm:132:18) // at Object.runInThisContext (node:vm:309:38) // at node:internal/process/execution:77:19 // at [eval]-wrapper:6:22 // at evalScript (node:internal/process/execution:76:60) // at node:internal/main/eval_string:23:3 const name = 'Will Robinson'; console.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to stderr ``` Example using the `Console` class: ```js const out = getStreamSomehow(); const err = getStreamSomehow(); const myConsole = new console.Console(out, err); myConsole.log('hello world'); // Prints: hello world, to out myConsole.log('hello %s', 'world'); // Prints: hello world, to out myConsole.error(new Error('Whoops, something bad happened')); // Prints: [Error: Whoops, something bad happened], to err const name = 'Will Robinson'; myConsole.warn(`Danger ${name}! Danger!`); // Prints: Danger Will Robinson! Danger!, to err ```
@see[source](https://github.com/nodejs/node/blob/v22.x/lib/console.js)
console
.Console.log(message?: any, ...optionalParams: any[]): void (+1 overload)
Prints to `stdout` with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to [`printf(3)`](http://man7.org/linux/man-pages/man3/printf.3.html) (the arguments are all passed to [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args)). ```js const count = 5; console.log('count: %d', count); // Prints: count: 5, to stdout console.log('count:', count); // Prints: count: 5, to stdout ``` See [`util.format()`](https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args) for more information.
@sincev0.1.100
log
(element: anyelement));
}

This function accepts any array type through the generic constraint T.

7. Mapped Types with Index Signatures

Square brackets in mapped types define index signatures to create dynamic property types.

type 
type StringMap<T> = {
    [key: string]: T;
}
StringMap
<function (type parameter) T in type StringMap<T>T> = { [key: stringkey: string]: function (type parameter) T in type StringMap<T>T };
let let map: StringMap<number>map:
type StringMap<T> = {
    [key: string]: T;
}
StringMap
<number> = { a: numbera: 1, b: numberb: 2 };

StringMap creates a type with string keys and values of type T.

8. Advanced Tuple Manipulation

Square brackets enable precise tuple manipulation for extracting or omitting elements.

type type WithoutFirst<T extends any[]> = T extends [any, ...infer Rest] ? Rest : []WithoutFirst<function (type parameter) T in type WithoutFirst<T extends any[]>T extends any[]> = function (type parameter) T in type WithoutFirst<T extends any[]>T extends [any, ...infer function (type parameter) RestRest] ? function (type parameter) RestRest : [];
type 
type Tail = [2, 3]
Tail
= type WithoutFirst<T extends any[]> = T extends [any, ...infer Rest] ? Rest : []WithoutFirst<[1, 2, 3]>;

WithoutFirst removes the first element from a tuple.

Conclusion

Square brackets in TypeScript provide essential functionality, from basic array definitions to complex type manipulations. These features make TypeScript code reliable and maintainable. The growing adoption of TypeScript demonstrates the practical benefits of its robust type system.

The TypeScript Handbook provides comprehensive documentation of these features. TypeHero offers hands-on practice through interactive challenges to master TypeScript concepts, including square bracket techniques for type manipulation. These resources will strengthen your command of TypeScript and expand your programming capabilities.

Questions or thoughts?

Follow me on X for more TypeScript, Vue, and web dev insights! Feel free to DM me with:

  • Questions about this article
  • Topic suggestions
  • Feedback or improvements
Connect on X

Related Posts