Created
January 6, 2026 16:31
-
-
Save renatorib/62d68ea5ab08aa1d4c4c25cb3366e5df to your computer and use it in GitHub Desktop.
Slack Block Kit TypeScript Types
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // JSON Schema: | |
| // https://gist.githubusercontent.com/lawrencegripper/ee24242249fc6a1a0a73c561766dd486/raw/54e8dea65f4b8a0d9eae0e4be656568076142999/blockkit.schema.json | |
| interface Actionable { | |
| action_id?: string; | |
| } | |
| interface Focusable { | |
| focus_on_load?: boolean; | |
| } | |
| interface Placeholdable { | |
| placeholder?: PlainTextElement; | |
| } | |
| export interface PlainTextElement { | |
| type: 'plain_text'; | |
| text: string; | |
| emoji?: boolean; | |
| } | |
| export interface MrkdwnElement { | |
| type: 'mrkdwn'; | |
| text: string; | |
| verbatim?: boolean; | |
| } | |
| export type TextElement = PlainTextElement | MrkdwnElement; | |
| export interface ConfirmationDialog { | |
| title?: PlainTextElement; | |
| text: TextElement; | |
| confirm?: PlainTextElement; | |
| deny?: PlainTextElement; | |
| style?: 'primary' | 'danger'; | |
| } | |
| export interface Button { | |
| type: 'button'; | |
| text: PlainTextElement; | |
| action_id?: string; | |
| url?: string; | |
| value?: string; | |
| style?: 'danger' | 'primary'; | |
| confirm?: ConfirmationDialog; | |
| accessibility_label?: string; | |
| } | |
| export interface Checkboxes extends Actionable, Focusable { | |
| type: 'checkboxes'; | |
| options: Option[]; | |
| initial_options?: Option[]; | |
| confirm?: ConfirmationDialog; | |
| } | |
| export type Option = PlainTextOption | MrkdwnOption; | |
| export interface PlainTextOption { | |
| text: PlainTextElement; | |
| value: string; | |
| description?: PlainTextElement; | |
| url?: string; | |
| } | |
| export interface MrkdwnOption { | |
| text: MrkdwnElement; | |
| value: string; | |
| description?: PlainTextElement; | |
| url?: string; | |
| } | |
| export interface StaticSelect extends Actionable, Focusable, Placeholdable { | |
| type: 'static_select'; | |
| options: PlainTextOption[]; | |
| initial_option?: PlainTextOption; | |
| } | |
| export interface UsersSelect extends Actionable, Focusable, Placeholdable { | |
| type: 'users_select'; | |
| initial_user?: string; | |
| } | |
| export interface ConversationsSelect extends Actionable, Focusable, Placeholdable { | |
| type: 'conversations_select'; | |
| initial_conversation?: string; | |
| default_to_current_conversation?: boolean; | |
| } | |
| export interface ChannelsSelect extends Actionable, Focusable, Placeholdable { | |
| type: 'channels_select'; | |
| initial_channel?: string; | |
| } | |
| export interface ExternalSelect extends Actionable, Focusable, Placeholdable { | |
| type: 'external_select'; | |
| initial_option?: PlainTextOption; | |
| min_query_length?: number; | |
| } | |
| export type Select = StaticSelect | UsersSelect | ConversationsSelect | ChannelsSelect | ExternalSelect; | |
| export type MultiSelect = | |
| | (Omit<StaticSelect, 'type' | 'initial_option'> & { | |
| type: 'multi_static_select'; | |
| initial_options?: PlainTextOption[]; | |
| }) | |
| | (Omit<UsersSelect, 'type' | 'initial_user'> & { type: 'multi_users_select'; initial_users?: string[] }) | |
| | (Omit<ConversationsSelect, 'type' | 'initial_conversation'> & { | |
| type: 'multi_conversations_select'; | |
| initial_conversations?: string[]; | |
| }) | |
| | (Omit<ChannelsSelect, 'type' | 'initial_channel'> & { type: 'multi_channels_select'; initial_channels?: string[] }) | |
| | (Omit<ExternalSelect, 'type' | 'initial_option'> & { | |
| type: 'multi_external_select'; | |
| initial_options?: PlainTextOption[]; | |
| }); | |
| // Elements | |
| export interface ImageElement { | |
| type: 'image'; | |
| image_url: string; | |
| alt_text: string; | |
| } | |
| export interface Datepicker extends Focusable, Placeholdable { | |
| type: 'datepicker'; | |
| action_id?: string; | |
| initial_date?: string; | |
| confirm?: ConfirmationDialog; | |
| } | |
| export interface Timepicker extends Focusable, Placeholdable { | |
| type: 'timepicker'; | |
| action_id?: string; | |
| initial_time?: string; | |
| timezone?: string; | |
| confirm?: ConfirmationDialog; | |
| } | |
| export interface DateTimepicker extends Focusable { | |
| type: 'datetimepicker'; | |
| action_id?: string; | |
| initial_date_time?: number; | |
| confirm?: ConfirmationDialog; | |
| } | |
| export interface Overflow { | |
| type: 'overflow'; | |
| action_id?: string; | |
| options: Option[]; | |
| confirm?: ConfirmationDialog; | |
| } | |
| export interface RadioButtons extends Focusable { | |
| type: 'radio_buttons'; | |
| action_id?: string; | |
| options: Option[]; | |
| initial_option?: Option; | |
| confirm?: ConfirmationDialog; | |
| } | |
| export interface WorkflowButton { | |
| type: 'workflow_button'; | |
| text: PlainTextElement; | |
| workflow: { | |
| trigger: { | |
| url: string; | |
| customizable_input_parameters?: Array<{ | |
| name: string; | |
| value: string; | |
| }>; | |
| }; | |
| }; | |
| style?: 'danger' | 'primary'; | |
| confirm?: ConfirmationDialog; | |
| accessibility_label?: string; | |
| } | |
| export interface DispatchActionConfig { | |
| trigger_actions_on?: Array<'on_enter_pressed' | 'on_character_entered'>; | |
| } | |
| export interface PlainTextInput { | |
| type: 'plain_text_input'; | |
| action_id?: string; | |
| placeholder?: PlainTextElement; | |
| initial_value?: string; | |
| multiline?: boolean; | |
| min_length?: number; | |
| max_length?: number; | |
| dispatch_action_config?: DispatchActionConfig; | |
| focus_on_load?: boolean; | |
| } | |
| export interface URLInput { | |
| type: 'url_text_input'; | |
| action_id?: string; | |
| initial_value?: string; | |
| placeholder?: PlainTextElement; | |
| dispatch_action_config?: DispatchActionConfig; | |
| focus_on_load?: boolean; | |
| } | |
| export interface EmailInput { | |
| type: 'email_text_input'; | |
| action_id?: string; | |
| initial_value?: string; | |
| placeholder?: PlainTextElement; | |
| dispatch_action_config?: DispatchActionConfig; | |
| focus_on_load?: boolean; | |
| } | |
| export interface NumberInput { | |
| type: 'number_input'; | |
| action_id?: string; | |
| is_decimal_allowed: boolean; | |
| initial_value?: string; | |
| min_value?: string; | |
| max_value?: string; | |
| placeholder?: PlainTextElement; | |
| dispatch_action_config?: DispatchActionConfig; | |
| focus_on_load?: boolean; | |
| } | |
| // Rich Text Types | |
| export interface RichTextStyle { | |
| bold?: boolean; | |
| italic?: boolean; | |
| strike?: boolean; | |
| highlight?: boolean; | |
| } | |
| export interface RichTextBroadcastMention { | |
| type: 'broadcast'; | |
| range: 'here' | 'channel' | 'everyone'; | |
| style?: RichTextStyle; | |
| } | |
| export interface RichTextColor { | |
| type: 'color'; | |
| value: string; | |
| style?: RichTextStyle; | |
| } | |
| export interface RichTextChannelMention { | |
| type: 'channel'; | |
| channel_id: string; | |
| style?: RichTextStyle; | |
| } | |
| export interface RichTextDate { | |
| type: 'date'; | |
| timestamp: number; | |
| format: string; | |
| style?: RichTextStyle; | |
| url?: string; | |
| fallback?: string; | |
| } | |
| export interface RichTextEmoji { | |
| type: 'emoji'; | |
| name: string; | |
| style?: RichTextStyle; | |
| unicode?: string; | |
| url?: string; | |
| } | |
| export interface RichTextLink { | |
| type: 'link'; | |
| url: string; | |
| style?: RichTextStyle; | |
| text?: string; | |
| unsafe?: boolean; | |
| } | |
| export interface RichTextTeamMention { | |
| type: 'team'; | |
| team_id: string; | |
| style?: RichTextStyle; | |
| } | |
| export interface RichTextText { | |
| type: 'text'; | |
| text: string; | |
| style?: RichTextStyle; | |
| } | |
| export interface RichTextUserMention { | |
| type: 'user'; | |
| user_id: string; | |
| style?: RichTextStyle; | |
| } | |
| export interface RichTextUsergroupMention { | |
| type: 'usergroup'; | |
| usergroup_id: string; | |
| style?: RichTextStyle; | |
| } | |
| export type RichTextElement = | |
| | RichTextBroadcastMention | |
| | RichTextColor | |
| | RichTextChannelMention | |
| | RichTextDate | |
| | RichTextEmoji | |
| | RichTextLink | |
| | RichTextTeamMention | |
| | RichTextText | |
| | RichTextUserMention | |
| | RichTextUsergroupMention; | |
| export interface RichTextSection { | |
| type: 'rich_text_section'; | |
| elements: RichTextElement[]; | |
| } | |
| export interface RichTextList { | |
| type: 'rich_text_list'; | |
| style: 'bullet' | 'ordered'; | |
| indent?: number; | |
| border?: number; | |
| elements: RichTextSection[]; | |
| } | |
| export interface RichTextQuote { | |
| type: 'rich_text_quote'; | |
| elements: RichTextElement[]; | |
| } | |
| export interface RichTextPreformatted { | |
| type: 'rich_text_preformatted'; | |
| elements: RichTextElement[]; | |
| border?: number; | |
| } | |
| export interface RichTextInput { | |
| type: 'rich_text_input'; | |
| action_id?: string; | |
| placeholder?: PlainTextElement; | |
| initial_value?: RichTextBlock; | |
| dispatch_action_config?: DispatchActionConfig; | |
| focus_on_load?: boolean; | |
| } | |
| // Blocks | |
| export type KnownBlock = | |
| | ImageBlock | |
| | ContextBlock | |
| | ActionsBlock | |
| | DividerBlock | |
| | SectionBlock | |
| | InputBlock | |
| | FileBlock | |
| | HeaderBlock | |
| | VideoBlock | |
| | RichTextBlock; | |
| export interface BaseBlock { | |
| block_id?: string; | |
| } | |
| export interface ImageBlock extends BaseBlock { | |
| type: 'image'; | |
| image_url: string; | |
| alt_text: string; | |
| title?: PlainTextElement; | |
| } | |
| export interface ContextBlock extends BaseBlock { | |
| type: 'context'; | |
| elements: (ImageElement | TextElement)[]; | |
| } | |
| export interface ActionsBlock extends BaseBlock { | |
| type: 'actions'; | |
| elements: ( | |
| | Button | |
| | Checkboxes | |
| | Select | |
| | MultiSelect | |
| | Datepicker | |
| | DateTimepicker | |
| | Timepicker | |
| | Overflow | |
| | RadioButtons | |
| | WorkflowButton | |
| | RichTextInput | |
| )[]; | |
| } | |
| export interface SectionBlock extends BaseBlock { | |
| type: 'section'; | |
| text?: TextElement; | |
| fields?: TextElement[]; | |
| accessory?: | |
| | Button | |
| | Overflow | |
| | Datepicker | |
| | Timepicker | |
| | Select | |
| | MultiSelect | |
| | ImageElement | |
| | RadioButtons | |
| | Checkboxes; | |
| } | |
| export interface DividerBlock extends BaseBlock { | |
| type: 'divider'; | |
| } | |
| export interface HeaderBlock extends BaseBlock { | |
| type: 'header'; | |
| text: PlainTextElement; | |
| } | |
| export interface InputBlock extends BaseBlock { | |
| type: 'input'; | |
| label: PlainTextElement; | |
| element: | |
| | Select | |
| | MultiSelect | |
| | Datepicker | |
| | Timepicker | |
| | DateTimepicker | |
| | PlainTextInput | |
| | URLInput | |
| | EmailInput | |
| | NumberInput | |
| | RadioButtons | |
| | Checkboxes | |
| | RichTextInput; | |
| hint?: PlainTextElement; | |
| optional?: boolean; | |
| dispatch_action?: boolean; | |
| } | |
| export interface FileBlock extends BaseBlock { | |
| type: 'file'; | |
| source: string; | |
| external_id: string; | |
| } | |
| export interface VideoBlock extends BaseBlock { | |
| type: 'video'; | |
| video_url: string; | |
| thumbnail_url: string; | |
| alt_text: string; | |
| title: PlainTextElement; | |
| title_url?: string; | |
| author_name?: string; | |
| provider_name?: string; | |
| provider_icon_url?: string; | |
| description?: PlainTextElement; | |
| } | |
| export interface RichTextBlock extends BaseBlock { | |
| type: 'rich_text'; | |
| elements: (RichTextSection | RichTextList | RichTextQuote | RichTextPreformatted)[]; | |
| } | |
| // Resulting Root Type | |
| export type SlackMessageBlocks = KnownBlock[]; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment