Array Type Utilities
Array type utilities provide tools for working with array types and extracting element information.
Element Type Extraction
ArrayItem
Extract the element type from an array type.
type ArrayItem<T extends readonly unknown[]> = T extends readonly (infer U)[] ? U : never;
// Examples
type StringArray = string[];
type StringItem = ArrayItem<StringArray>; // string
type NumberArray = number[];
type NumberItem = ArrayItem<NumberArray>; // number
type MixedArray = (string | number | boolean)[];
type MixedItem = ArrayItem<MixedArray>; // string | number | boolean
Tuple Type Handling
Working with Tuples
ArrayItem
works seamlessly with tuple types:
type UserTuple = [string, number, boolean];
type UserTupleItem = ArrayItem<UserTuple>; // string | number | boolean
type CoordinateTuple = [number, number];
type CoordinateItem = ArrayItem<CoordinateTuple>; // number
type NamedTuple = [name: string, age: number, active: boolean];
type NamedTupleItem = ArrayItem<NamedTuple>; // string | number | boolean
Readonly Array Support
Readonly Arrays
The utility supports both mutable and readonly arrays:
type ReadonlyStringArray = readonly string[];
type ReadonlyStringItem = ArrayItem<ReadonlyStringArray>; // string
type ReadonlyTuple = readonly [string, number];
type ReadonlyTupleItem = ArrayItem<ReadonlyTuple>; // string | number
// Const assertions create readonly tuples
const colors = ['red', 'green', 'blue'] as const;
type ColorsArray = typeof colors; // readonly ["red", "green", "blue"]
type ColorItem = ArrayItem<ColorsArray>; // "red" | "green" | "blue"
Real-World Examples
API Response Processing
import type { ArrayItem } from 'typescript-api-pro';
interface User {
id: number;
name: string;
email: string;
}
type UsersResponse = User[];
type SingleUser = ArrayItem<UsersResponse>; // User
// Function that processes individual users
function processUser(user: SingleUser) {
console.log(`Processing user: ${user.name}`);
}
// Usage with array methods
const users: UsersResponse = [
{ id: 1, name: 'John', email: 'john@example.com' },
{ id: 2, name: 'Jane', email: 'jane@example.com' }
];
users.forEach(processUser); // TypeScript knows the parameter type
Generic Array Processing
import type { ArrayItem } from 'typescript-api-pro';
// Generic function that works with any array type
function getFirstItem<T extends readonly unknown[]>(
array: T
): ArrayItem<T> | undefined {
return array[0] as ArrayItem<T> | undefined;
}
// Usage examples
const numbers = [1, 2, 3, 4, 5];
const firstNumber = getFirstItem(numbers); // number | undefined
const strings = ['hello', 'world'];
const firstString = getFirstItem(strings); // string | undefined
const mixed = [1, 'hello', true] as const;
const firstMixed = getFirstItem(mixed); // 1 | "hello" | true | undefined
Form Field Arrays
import type { ArrayItem } from 'typescript-api-pro';
interface FormField {
name: string;
type: 'text' | 'email' | 'password' | 'number';
required: boolean;
placeholder?: string;
}
type FormFields = FormField[];
type SingleField = ArrayItem<FormFields>; // FormField
// Validation function for individual fields
function validateField(field: SingleField): boolean {
if (field.required && !field.name) {
return false;
}
return true;
}
// Form configuration
const loginForm: FormFields = [
{ name: 'email', type: 'email', required: true, placeholder: 'Enter your email' },
{ name: 'password', type: 'password', required: true, placeholder: 'Enter your password' }
];
// Validate all fields
const isFormValid = loginForm.every(validateField);
Event Handler Arrays
import type { ArrayItem } from 'typescript-api-pro';
type EventHandler = (event: Event) => void;
type EventHandlers = EventHandler[];
type SingleHandler = ArrayItem<EventHandlers>; // EventHandler
// Event manager
class EventManager {
private handlers: EventHandlers = [];
addHandler(handler: SingleHandler) {
this.handlers.push(handler);
}
removeHandler(handler: SingleHandler) {
const index = this.handlers.indexOf(handler);
if (index > -1) {
this.handlers.splice(index, 1);
}
}
trigger(event: Event) {
this.handlers.forEach(handler => handler(event));
}
}
Configuration Arrays
import type { ArrayItem } from 'typescript-api-pro';
interface DatabaseConnection {
host: string;
port: number;
database: string;
ssl?: boolean;
}
type DatabaseConnections = DatabaseConnection[];
type SingleConnection = ArrayItem<DatabaseConnections>; // DatabaseConnection
// Connection pool manager
class ConnectionPool {
private connections: DatabaseConnections = [];
addConnection(connection: SingleConnection) {
this.connections.push(connection);
}
getConnection(database: string): SingleConnection | undefined {
return this.connections.find(conn => conn.database === database);
}
getAllConnections(): DatabaseConnections {
return [...this.connections];
}
}
// Usage
const pool = new ConnectionPool();
pool.addConnection({
host: 'localhost',
port: 5432,
database: 'users',
ssl: true
});
Type Safety Benefits
Compile-Time Validation
import type { ArrayItem } from 'typescript-api-pro';
// Type-safe array processing
function processItems<T extends readonly unknown[]>(
items: T,
processor: (item: ArrayItem<T>) => void
) {
items.forEach(processor);
}
// Usage - TypeScript ensures type safety
const numbers = [1, 2, 3];
processItems(numbers, (num) => {
console.log(num.toFixed(2)); // TypeScript knows num is number
});
const strings = ['a', 'b', 'c'];
processItems(strings, (str) => {
console.log(str.toUpperCase()); // TypeScript knows str is string
});
Integration with Other Utilities
import type { ArrayItem, ValueOf } from 'typescript-api-pro';
interface Product {
id: number;
name: string;
price: number;
categories: string[];
}
type Products = Product[];
type SingleProduct = ArrayItem<Products>; // Product
type ProductValue = ValueOf<SingleProduct>; // number | string | string[]
type ProductCategory = ArrayItem<SingleProduct['categories']>; // string