# Custom types

> **Info:** This is release candidate documentation for **Stream Chat Angular SDK v8**. For the latest stable version, see the [latest version (v7)](https://getstream.io/chat/docs/sdk/angular/).

Most Stream entities (such as channel, message, user etc.) let you store custom data. Custom data lives under the `custom` object of the entity (for example `channel.data.custom`, `message.custom`, `user.custom`, `attachment.custom` or `reaction.custom`). To make it easier to work with that data you can use declaration merging to define the shape of your custom data.

[Full list of custom interfaces](https://github.com/GetStream/stream-chat-js/blob/release-v10/src/custom_types.ts)

The SDK defines some custom properties that are used within the SDK. To get proper type checking for these you need to create a `d.ts` file, for example `src/app/stream-chat.d.ts`:

```ts
import { DefaultAttachmentData, DefaultChannelData } from "stream-chat-angular";

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

  interface CustomAttachmentData extends DefaultAttachmentData {}
}
```

[Full list of SDK custom interfaces](https://github.com/GetStream/stream-chat-angular/blob/master/projects/stream-chat-angular/src/lib/types-custom.ts)

It's also possible to add your own custom fields:

```typescript
import { DefaultAttachmentData, DefaultChannelData } from "stream-chat-angular";

declare module "stream-chat" {
  interface CustomChannelData extends DefaultChannelData {
    color: string;
    topic: "gardening" | "cats" | "f1";
  }

  interface CustomUserData {
    nickname: string;
  }

  interface CustomMessageData {
    isSecret: boolean;
  }

  interface CustomAttachmentData extends DefaultAttachmentData {
    lat?: string;
    lon?: string;
  }

  interface CustomReactionData {
    // Turn off type checks for custom properties
    [key: string]: unknown;
  }
}
```

Required fields you declare (such as `color` or `nickname` above) are required in every `custom` object of that entity, including the ones you create. Use optional fields if that's not what you want.

Then your custom data will be properly typed under `custom`:

```typescript
import type {
  Attachment,
  Channel,
  ReactionResponse,
  UserResponse,
} from "stream-chat";
import type { StreamMessage } from "stream-chat-angular";

let channel: Channel | undefined;
console.log(channel?.data?.custom?.topic);

let user: UserResponse | undefined;
console.log(user?.custom.nickname);

let message: StreamMessage | undefined;
console.log(message?.custom.isSecret);

let attachment: Attachment | undefined;
console.log(attachment?.custom.lat);
console.log(attachment?.custom.lon);

let reaction: ReactionResponse | undefined;
// CustomReactionData allows any key on reaction.custom
console.log(reaction?.custom.foo);
```

>
> **Note:** In `stream-chat` v10 the `User` and `Reaction` types mean something else than before (they aren't chat users and reactions anymore). Use `UserResponse` and `ReactionResponse` instead.
>

If you don't want type checks for custom properties you can define the custom interface like this:

```ts
interface CustomMessageData {
  // Turn off type checks for custom properties
  [key: string]: unknown;
}
```

---

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/sdk/angular/v8/concepts/custom-types/](https://getstream.io/chat/docs/sdk/angular/v8/concepts/custom-types/).