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), 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 eleven extendable interfaces within stream-chat, which are merged 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

Note that CustomChannelData are extended within stream-chat-react SDK with commonly used custom data (subtitle, image and name living in a reusable interface DefaultChannelData), these declarations do not interfere with integrator-defined declarations and extending your declarations with the SDK-supplied defaults (see bellow) is not necessary but note that certain default components expect these to be of specific type and different types (and actual values) may lead to unexpected behavior. If you decide to use different types for this data, make sure you replace affected default components as well.

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:

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;
  }
}

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.

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

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
© Getstream.io, Inc. All Rights Reserved.