# Typing If you are using TypeScript in your project, you can leverage built-in TypeScript support to ensure type safety and enable autocompletion when working with the channel object. ## Provide a type for the channel object You can provide a type parameter to the `channel.object.get()` method to specify the expected structure of the channel object: ```javascript import { LiveCounter, LiveMap } from 'ably/liveobjects'; // Define the expected structure of your channel object type MyObject = { visits: LiveCounter; reactions: LiveMap<{ likes: LiveCounter; hearts: LiveCounter; }>; settings: LiveMap<{ theme: string; notifications: boolean; }>; }; // Get a typed PathObject for the channel const myObject = await channel.object.get(); ``` This enables TypeScript to infer the correct types when accessing and mutating objects. TypeScript surfaces the correct set of methods that are expected for the current `Instance` or `PathObject` and infers the correct arguments and return values for all methods: ```javascript // TypeScript knows 'visits' is a LiveCounter const visits = myObject.get('visits'); await visits.increment(5); // Type-safe // TypeScript knows the structure of 'reactions' const reactions = myObject.get('reactions'); const likes = reactions.get('likes'); await likes.increment(1); // Type-safe // TypeScript knows 'theme' is a string const theme = myObject.get('settings').get('theme'); const themeValue: string | undefined = theme.value(); // Type errors are caught at compile time await reactions.set('likes', 'invalid'); // Error: Argument of type 'string' is not assignable to parameter of type 'LiveCounter' ``` When obtaining [Instance](https://ably.com/docs/liveobjects/concepts/instance) objects, TypeScript automatically infers the correct instance type: ```javascript type MyObject = { visits: LiveCounter; settings: LiveMap<{ theme: string; }>; }; const myObject = await channel.object.get(); const visits = myObject.get('visits').instance(); await visits?.increment(1); // TypeScript knows visits is an Instance of a LiveCounter const value: number | undefined = visits?.value(); // TypeScript knows the LiveCounter has a number value const settings = myObject.get('settings').instance(); await settings?.set('theme', 'dark'); // TypeScript knows settings is an Instance of a LiveMap const theme: string | undefined = settings?.get('theme'); ``` TypeScript also infers the correct instance type when using [batch operations](https://ably.com/docs/liveobjects/batch): ```javascript type MyObject = { visits: LiveCounter; settings: LiveMap<{ theme: string; }>; }; const myObject = await channel.object.get(); await myObject.batch((ctx) => { const visits = ctx.get('visits'); visits?.increment(1); // TypeScript knows visits is a LiveCounter const value: number | undefined = visits?.value(); // TypeScript knows the LiveCounter has a number value const settings = ctx.get('settings'); settings?.set('theme', 'dark'); // TypeScript knows settings is a LiveMap const theme: string | undefined = settings?.get('theme'); }); ``` ## Define reusable types You can define and export types for reuse across your application: ```javascript // types/liveobjects.ts import { LiveCounter, LiveMap } from 'ably/liveobjects'; export type ReactionsType = { likes: LiveCounter; hearts: LiveCounter; fire: LiveCounter; }; export type UserProfileType = { name: string; score: LiveCounter; settings: LiveMap<{ theme: string; notifications: boolean; }>; }; export type ChannelObjectType = { reactions: LiveMap; users: LiveMap<{ [userId: string]: LiveMap; }>; }; ``` Then import and use these types where needed: ```javascript import type { ChannelObjectType } from './types/liveobjects'; const myObject = await channel.object.get(); // Fully typed access const userScore = myObject .get('users') .get('user123') .get('score'); await userScore.increment(10); // Type-safe ``` ## Use per-channel types When your application uses multiple channels with different object structures, you can specify different types for each: ```javascript // Define types for different channels type ReactionsChannelObject = { likes: LiveCounter; hearts: LiveCounter; }; type LeaderboardChannelObject = { players: LiveMap<{ [playerId: string]: LiveMap<{ name: string; score: LiveCounter; }>; }>; }; // Get typed objects for different channels const reactionsChannel = client.channels.get('reactions'); const reactions = await reactionsChannel.object.get(); const leaderboardChannel = client.channels.get('leaderboard'); const leaderboard = await leaderboardChannel.object.get(); // Each channel has its own type safety await reactions.get('likes').increment(1); // Type-safe for reactions const players = leaderboard.get('players'); // Type-safe for leaderboard ```