bolt-js icon indicating copy to clipboard operation
bolt-js copied to clipboard

Types are difficult to use

Open pwmcintyre opened this issue 8 months ago • 2 comments

When trying to use the following template, but converted to TypeScript, I get a type error with the SDK that I don't understand.

Template: https://github.com/slack-samples/bolt-js-assistant-template

When converting from app.js to app.ts and attempting to transpile, you get endless errors.

When attempting to troubleshot and understand the types provided, you met with very deeply nested chains of types which are difficult to understand.

I guess my questions is — is it even productive to use typescript with Bolt? Is everyone just using JavaScript now? What do you recommend? Are the below specific issues a bug?

This old issue seems to still hold true: https://github.com/slackapi/bolt-js/issues/826

Additionally, having same types not exported doesn't help

See below for example errors.

@slack/bolt version

4.2.1

Your App and Receiver Configuration

see template

Node.js runtime version

v20.16.0

Steps to reproduce:

git clone https://github.com/slack-samples/bolt-js-assistant-template.git
cd bolt-js-assistant-template
npm install
npm i -D typescript ts-node
mv app.js app.ts
npx ts-node ./app.ts

Expected result:

Maybe my expectations are too high, but I didn't expect so many type issues to troubleshoot, for example the first one beats me (see below error).

The infered type of the prompts array looks satisfactory, but for whatever reason it doesn't work.

Here is the type: https://github.com/slackapi/bolt-js/blob/e6f3f1ca8260e0f0ad8465e6a763f21c2846f843/src/Assistant.ts#L47-L59

I had to research as to why you use this type:

prompts: [AssistantPrompt, ...AssistantPrompt[]];

It's a "non-empty array" type, which may be more trouble than it's worth? (How can you even check the array size at compile time?)

Interestingly if I make this change to the interface, the typescript is happy

prompts: AssistantPrompt[];

Or if you could export the type, then I could import them type and force it like so:

const prompts: [AssistantPrompt, ...AssistantPrompt[]] = [
...

Actual result:

Many errors including:

app.ts:82:35 - error TS2322: Type '{ title: string; message: string; }[]' is not assignable to type '[AssistantPrompt, ...AssistantPrompt[]]'.
  Source provides no match for required element at position 0 in target.

82       await setSuggestedPrompts({ prompts, title: 'Here are some suggested options:' });
                                     ~~~~~~~

  node_modules/@slack/bolt/dist/Assistant.d.ts:30:5
    30     prompts: [AssistantPrompt, ...AssistantPrompt[]];
           ~~~~~~~
    The expected type comes from property 'prompts' which is declared here on type 'SetSuggestedPromptsArguments'

sorry for the rant — but it remains really challenging to use Typescript with Slack 😞

pwmcintyre avatar Apr 22 '25 13:04 pwmcintyre

Hi there,

We do have the basic BoltJS template in Typescript, which might be a better starting place: https://github.com/slack-samples/bolt-ts-starter-template

It unfortunately doesn't have Agent/Assistant support as the bolt-js-assistant-template template does. We'll note this as a request for more Typescript-based templates for BoltJS! We currently only have the starter template and the custom function template.

vegeris avatar Apr 23 '25 20:04 vegeris

+1 the new Agent/Assistant flow is not properly typed yet. For example the message object on the userMessage function is missing several key properties on it's type that exist on the code.

The code for this example: https://tools.slack.dev/bolt-js/concepts/ai-apps#handling-user-response

userMessage: async ({ client, logger, message, say, setTitle, setStatus }) => {
   const { channel, thread_ts } = message;

   try {
     // Set the status of the Assistant to give the appearance of active processing.
     await setStatus('is typing..');

     // Retrieve the Assistant thread history for context of question being asked
     const thread = await client.conversations.replies({
       channel,
       ts: thread_ts,
       oldest: thread_ts,
     });

     // Prepare and tag each message for LLM processing
     const userMessage = { role: 'user', content: message.text };

Will throw multiple typescript errors, for example message.thread_ts or message.text are not defined according to typescript (but of course those props exists) the type of message actually evaluates to something random like KnownEventFromType<"message">

bieblebrox avatar May 26 '25 19:05 bieblebrox

👋 It looks like this issue has been open for 30 days with no activity. We'll mark this as stale for now, and wait 10 days for an update or for further comment before closing this issue out. If you think this issue needs to be prioritized, please comment to get the thread going again! Maintainers also review issues marked as stale on a regular basis and comment or adjust status if the issue needs to be reprioritized.

github-actions[bot] avatar Jun 30 '25 00:06 github-actions[bot]

🗣️ A change of https://github.com/slackapi/node-slack-sdk/pull/2297 to @slack/types will soon be released and brought to @slack/bolt to improve this typing!

We've since also added typescript checks to the linked sample in https://github.com/slack-samples/bolt-js-assistant-template/pull/46 as well.

zimeg avatar Jul 12 '25 01:07 zimeg