
Ts Object Types in TypeScript
In TypeScript, object types are used to define the shape of objects, specifying their properties, types, and structure. This enables type safety and autocompletion when working with objects. You can create object types using interfaces, type aliases, or inline annotations.
Defining Object Types
Inline Object Type AnnotationUse inline annotations to specify the structure of an object directly.
const person: { name: string; age: number } = { name: "Alice", age: 30,};
Using Type AliasesDefine reusable object types with
type
.type Person = { name: string; age: number;};const person: Person = { name: "Bob", age: 25,};
Using InterfacesInterfaces are a common way to define object types and support inheritance.
interface Person { name: string; age: number;}const person: Person = { name: "Charlie", age: 35,};
Optional Properties
You can make properties optional using the ?
modifier.
type Car = { make: string; model?: string; // Optional property};const car1: Car = { make: "Toyota" }; // Validconst car2: Car = { make: "Honda", model: "Civic" }; // Valid
Readonly Properties
Use the readonly
modifier to make properties immutable after initialization.
type Book = { readonly title: string; pages: number;};const book: Book = { title: "TypeScript Handbook", pages: 300 };// book.title = "Another Title"; // Error: Cannot assign to 'title' because it is a read-only property.
Index Signatures
Use index signatures to define objects with dynamic keys.
type Dictionary = { [key: string]: number;};const scores: Dictionary = { math: 90, science: 85,};// scores.english = "A"; // Error: Type 'string' is not assignable to type 'number'.
Nested Object Types
You can define nested object structures by combining types.
type Address = { street: string; city: string; zipCode: string;};type User = { name: string; age: number; address: Address;};const user: User = { name: "David", age: 40, address: { street: "123 Main St", city: "Metropolis", zipCode: "12345", },};
Union and Intersection with Object Types
Union TypesAn object can conform to one of several possible shapes.
type Dog = { breed: string; bark: () => void };type Cat = { breed: string; meow: () => void };type Pet = Dog | Cat;const pet: Pet = { breed: "Labrador", bark: () => console.log("Woof!"),};
Intersection TypesAn object must conform to all specified shapes.
type Point = { x: number };type Labeled = { label: string };type LabeledPoint = Point & Labeled;const point: LabeledPoint = { x: 10, label: "Center" };
Type Inference with Objects
If TypeScript can infer the type of an object, you may not need explicit annotations.
const user = { name: "Emma", age: 28,};// TypeScript infers the type as { name: string; age: number }
Extending Object Types
Extending InterfacesUse the
extends
keyword to extend interfaces.interface Animal { name: string;}interface Dog extends Animal { breed: string;}const dog: Dog = { name: "Buddy", breed: "Golden Retriever" };
Type Aliases with IntersectionsCombine types using
&
.type Animal = { name: string };type Dog = Animal & { breed: string };const dog: Dog = { name: "Buddy", breed: "Labrador" };
Key Utility Types for Objects
TypeScript provides several utility types for working with objects:
Partial<T>
Makes all properties optional.type User = { name: string; age: number };type PartialUser = Partial<User>;const user: PartialUser = { name: "Alice" }; // Valid
Readonly<T>
Makes all properties readonly.type ReadonlyUser = Readonly<User>;const user: ReadonlyUser = { name: "Alice", age: 30 };// user.name = "Bob"; // Error
Pick<T, K>
Selects specific properties from a type.type NameOnly = Pick<User, "name">;const user: NameOnly = { name: "Alice" };
Omit<T, K>
Excludes specific properties from a type.const user: WithoutAge = { name: "Alice" };
Best Practices for Object Types in TypeScript
- Use interfaces for defining object types unless you need advanced features of type aliases.
- Prefer readonly for properties that should not change after initialization.
- Use utility types like
Pick
,Omit
, orPartial
to simplify type manipulation. - Enable strictNullChecks to avoid unexpected
null
orundefined
values in objects.
Conclusion
Object types in TypeScript allow you to define structured, type-safe objects. They provide flexibility through interfaces, type aliases, utility types, and advanced features like unions and intersections. Understanding and effectively using object types can help you write more robust and maintainable code.