# TypeScript & Custom Data Types

As of version `5.0.0`, `stream-chat-react` has been converted to TypeScript. The `stream-chat` library was converted to TypeScript in version `2.0.0`. These upgrades not only improve the type safety, but also allow integrator-defined typings to be taken into consideration when working with Stream entities such as `message` or `channel` through the use of [module augmentation (declaration merging)](https://www.typescriptlang.org/docs/handbook/declaration-merging.html), which is a direct replacement for the previous type augmentation mechanism (generics) since `stream-chat` version `9.0.0` and `stream-chat-react` version `13.0.0`.

There are [twelve](https://github.com/GetStream/stream-chat-js/blob/fix/remove-stream-chat-generics/src/custom_types.ts) extendable interfaces in `stream-chat`, which merge with the base types of Stream entities:

1. `CustomAttachmentData`
2. `CustomChannelData`
3. `CustomCommandData`
4. `CustomEventData`
5. `CustomMemberData`
6. `CustomMessageData`
7. `CustomPollOptionData`
8. `CustomPollData`
9. `CustomReactionData`
10. `CustomUserData`
11. `CustomThreadData`
12. `CustomMessageComposerData`

## Best Practices

- Use module augmentation to keep custom data types centralized.
- Extend `DefaultChannelData` if you rely on default UI components.
- Keep custom types minimal to avoid bloated payloads.
- Regenerate or re-check types after SDK upgrades.
- Use `unknown` for command payloads when only keys matter.

<admonition type="warning">

Note that `CustomChannelData` is extended within `stream-chat-react` with commonly used fields (`subtitle`, `image`, `name`) in `DefaultChannelData`. Extending your declarations with these defaults (see below) isn’t required, but some default components expect specific types. If you change those types, you may need to replace the affected defaults.

</admonition>

## Declare Custom Data Types

To extend these custom interfaces you'll have to create a declaration file within your codebase and make sure it's loaded by the TypeScript. Within this file we'll import `stream-chat` and specific defaults from `stream-chat-react` and then define the interface augmentations:

```ts title="stream-custom-data.d.ts"
import "stream-chat";
import type { DefaultChannelData } from "stream-chat-react";

declare module "stream-chat" {
  interface CustomChannelData extends DefaultChannelData {}

  interface CustomMessageData {
    custom_property?: string;
  }

  interface CustomUserData {
    profile_picture?: string;
  }

  interface CustomCommandData {
    "custom-command": unknown;
    "other-custom-command": unknown;
  }
}
```

<admonition type="info">

Note that `CustomCommandData` interface is a special case from which only the keys would be used, the value type _is not important_ and `unknown` would suffice.

</admonition>

That's it, you can check if your augmentations work with similar code:

```ts
import { StreamChat } from "stream-chat";

const client = new StreamChat("any-key");

const response = await client.getMessage("id");

const customProperty = response.message.custom_property; // should be `string | undefined` as per our declaration
```


---

This page was last updated at 2026-05-29T10:51:41.940Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/react/v13/guides/typescript-and-custom-data-types/](https://getstream.io/chat/docs/sdk/react/v13/guides/typescript-and-custom-data-types/).