Designs complex generic types, refactors `any` types to strict alternatives, creates type guards and utility types, and resolves TypeScript compiler errors. Use when the user asks about TypeScript (TS) types, generics, type inference, type guards, removing `any` types, strict typing, type errors, `infer`, `extends`, conditional types, mapped types, template literal types, branded/opaque types, or utility types like `Partial`, `Record`, `ReturnType`, and `Awaited`.
97
97%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Passed
No known issues
[number]In TypeScript, you can access array element types using indexed access types. The [number] syntax is particularly powerful for extracting a union of all possible element types from an array or tuple.
Just like you can access object properties with string keys, you can access array elements with numeric indices:
const roles = ["user", "admin", "anonymous"] as const;
// Access specific index
type FirstRole = typeof roles[0]; // "user"
type SecondRole = typeof roles[1]; // "admin"
// Access all elements with [number]
type AnyRole = typeof roles[number]; // "user" | "admin" | "anonymous"[number] WorksThe number type, when used as an index, represents a union of ALL possible numeric indices. TypeScript uses this as a shortcut to access all elements:
// This is conceptually equivalent to:
type AnyRole = typeof roles[0 | 1 | 2];
// But [number] handles any array length automaticallyconst userAccessModel = {
user: ["update-self", "view"],
admin: ["create", "update-self", "update-any", "delete", "view"],
anonymous: ["view"],
} as const;
type Role = keyof typeof userAccessModel;
// Type: "user" | "admin" | "anonymous"
// Get all values (arrays) as a union
type UserAccessModelValues = typeof userAccessModel[Role];
// Type: readonly ["update-self", "view"] | readonly ["create", ...] | readonly ["view"]
// Get all actions from all roles
type Action = typeof userAccessModel[Role][number];
// Type: "update-self" | "view" | "create" | "update-any" | "delete"// Tuple - fixed length, specific types at each position
const tuple = ["hello", 42, true] as const;
type TupleElements = typeof tuple[number]; // "hello" | 42 | true
// Array - variable length, single element type
const array: string[] = ["a", "b", "c"];
type ArrayElement = typeof array[number]; // stringCombined with Parameters<>, you can get a union of all parameter types:
const funcWithManyParameters = (
a: string,
b: string,
c: number,
d: boolean,
) => {
return [a, b, c, d].join(" ");
};
// Get tuple of all parameter types
type ParamsTuple = Parameters<typeof funcWithManyParameters>;
// Type: [string, string, number, boolean]
// Get union of all parameter types
type ParamsUnion = Parameters<typeof funcWithManyParameters>[number];
// Type: string | number | booleanconst userAccessModel = {
user: ["update-self", "view"],
admin: ["create", "update-self", "update-any", "delete", "view"],
anonymous: ["view"],
} as const;
type Role = keyof typeof userAccessModel;
type Action = typeof userAccessModel[Role][number];
const canUserAccess = (role: Role, action: Action): boolean => {
// Need to cast because TypeScript can't narrow the array type
return (userAccessModel[role] as ReadonlyArray<Action>).includes(action);
};
// Type-safe usage
canUserAccess("admin", "delete"); // OK
canUserAccess("user", "delete"); // OK at compile time, false at runtime
canUserAccess("admin", "invalid"); // Error: "invalid" is not assignable to Actionas const on Arrays// BAD - elements widened to string
const actions = ["view", "edit", "delete"];
type Action = typeof actions[number]; // string
// GOOD - literal types preserved
const actions = ["view", "edit", "delete"] as const;
type Action = typeof actions[number]; // "view" | "edit" | "delete"When using .includes() on readonly arrays, you may need to cast:
const items = ["a", "b", "c"] as const;
type Item = typeof items[number];
// Error: Argument of type 'string' is not assignable to parameter of type '"a" | "b" | "c"'
const hasItem = items.includes(someString);
// Solution: Cast the array
const hasItem = (items as ReadonlyArray<Item>).includes(value as Item);You can combine [number] with conditional types:
type ExtractArrayElements<T> = T extends readonly (infer U)[] ? U : never;
const permissions = ["read", "write", "admin"] as const;
type Permission = ExtractArrayElements<typeof permissions>;
// Type: "read" | "write" | "admin"