Skip to content

JSX component types incompatible with JSX.Element (TS2786 on all card components) #103

@kirk-marple

Description

@kirk-marple

Bug Description

All card component functions (Card, CardText, Actions, Select, SelectOption, Button) produce TS2786 when used as JSX components with the /** @jsxImportSource chat */ pragma. The JSX runtime is correctly wired — jsx() returns CardJSXElement — but TypeScript checks each component's declared return type against JSX.Element, and they don't match.

Five distinct type issues:

  1. Return types don't satisfy JSX.ElementCard() returns CardElement, but JSX.Element is CardJSXElement (requires $$typeof, props). Same for all components.
  2. Text parameter shapeText(content: string) takes a string, but JSX passes {children: string}.
  3. Actions parameter shapeActions(children: array) takes an array, but JSX passes {children: Element}.
  4. Select props disconnectSelectOptions has options: SelectOptionElement[], but JSX SelectProps uses children. The JSX props interfaces exist but aren't connected to the function signatures.
  5. No IntrinsicAttributeskey prop errors on components in .map() loops.

Steps to Reproduce

  1. Create a .tsx file with /** @jsxImportSource chat */ pragma
  2. Import card components from 'chat'
  3. Use any component as JSX: <Card title="test"><CardText>hello</CardText></Card>
  4. Run tsc --noEmit

Expected Behavior

JSX compiles without errors, as documented in the SDK's cards guide.

Actual Behavior

Every JSX component produces TS2786 and/or TS2322:

error TS2786: 'Card' cannot be used as a JSX component.
  Its return type 'CardElement' is not a valid JSX element.
    Type 'CardElement' is missing the following properties from type 'CardJSXElement<CardJSXProps>': $$typeof, props

Code Sample

/** @jsxImportSource chat */
import { Card, CardText, Actions, Button } from 'chat';

// TS2786 on Card, CardText, Actions, and Button
const card = (
  <Card title="Order #1234">
    <CardText>Total: $50.00</CardText>
    <Actions>
      <Button id="approve" style="primary">Approve</Button>
    </Actions>
  </Card>
);


tsconfig.json relevant settings:

{
  "jsx": "react-jsx",
  "isolatedModules": true,
  "moduleResolution": "bundler"
}

Chat SDK Version

4.14.0

Node.js Version

24.12.0

Platform Adapter

Slack

Operating System

Linux

Additional Context

The root cause is in jsx-runtime-Bdt1Dwzf.d.ts: component functions are typed for the function-call API (returning CardElement, TextElement, etc.) but JSX.Element requires CardJSXElement. The JSX-specific props interfaces (CardProps, TextProps, SelectProps with children?: unknown) exist in the declarations but aren't used by the function signatures.

Workaround: The function-call API is fully type-safe:

import { Card, Text, Actions, Button } from 'chat';

const card = Card({
  title: 'Order #1234',
  children: [
    Text('Total: $50.00'),
    Actions([Button({ id: 'approve', label: 'Approve', style: 'primary' })]),
  ],
});

Suggested fix: Add JSX-compatible overloads or widen JSX.Element to accept the plain element types. Also define IntrinsicAttributes with key?: string.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions