reactjstypescriptspfx

error TS7031/TS7006/TS2339: Binding element 'dispatch'/ 'next' / 'action' / 'checked' implicitly has an 'any' type


I cloned an react spfx app from github. Because I cannot build it because of old depricated modules I try to build a new solution from scratch. Now I stuck with the error:

Binding element 'X' implicitly has an 'any' type.

Why do I get this error and how to fix it?

import * as React from 'react';
import styles from './SpfxTestKhhaWebpart.module.scss';
import type { ISpfxTestKhhaWebpartProps } from './ISpfxTestKhhaWebpartProps';
import "../assets/webchat.js";

export default class SpfxTestKhhaWebpart extends React.Component<ISpfxTestKhhaWebpartProps, {}> {
  constructor(props: ISpfxTestKhhaWebpartProps) {
    super(props);
    this.state = {
      checked: false
    };
  }

  public render(): React.ReactElement<ISpfxTestKhhaWebpartProps> {
    const styleOptions = {
      // Add styleOptions to customize web chat canvas
      hideUploadButton: true
    };

    const theURL = "https://powerva.microsoft.com/api/botmanagement/v1/directline/directlinetoken?botId=" + this.props.botid;

    const store = (window as any).WebChat.createStore(
      {},
      ({ dispatch }) => next => action => {
        if (action.type === "DIRECT_LINE/CONNECT_FULFILLED") {
          dispatch({
            meta: {
              method: "keyboard",
            },
            payload: {
              activity: {
                channelData: {
                  postBack: true,
                },
                //Web Chat will show the 'Greeting' System Topic message which has a trigger-phrase 'hello'
                name: 'startConversation',
                type: "event"
              },
            },
            type: "DIRECT_LINE/POST_ACTIVITY",
          });
        }
        return next(action);
      }
    );
    fetch(theURL)
      .then(response => response.json())
      .then(conversationInfo => {
        (window as any).WebChat.renderWebChat(
          {
            directLine: (window as any).WebChat.createDirectLine({
              token: conversationInfo.token,
            }),
            store: store,
            styleOptions: styleOptions
          },
          document.getElementById('webchat')
        );
      })
      .catch(err => console.error("An error occurred: " + err));

    return (

      <div className={styles.spfxTestKhhaWebpart}>

        {(this.state.checked) ?
          (
            <div className={styles.container}>
              <div className={styles.row}>
                <div className={styles.header} id="header">
                  <div className={styles.header_content_container}>
                    <div className={styles.header_image_container}>
                      <img className={styles.header_image} src={this.props.botlogo} />
                    </div>
                    <div className={styles.header_title_container}>
                      <div className={styles.header_title}>
                        <span className={styles.title_text}>{this.props.botname}</span>
                        <span className={styles.close} onClick={() => { this.setState({ checked: !this.state.checked }) }}>x</span>
                      </div>
                    </div>
                  </div>
                </div>
                <div className={styles.webchat} id="webchat" role="main"></div>
              </div></div>)
          : (
            <div className={styles.botimage_container}>
              <div className={styles.chatbot_image}>
                <img src={this.props.botimage} style={{ maxHeight: 150 }} onClick={() => { this.setState({ checked: !this.state.checked }) }} />
              </div>
            </div>)
        }
      </div >
    );
  }
}

Versions:

spfx-test-khha@0.0.1 C:\SPFX\test2 ├── @fluentui/react@8.112.8 ├── @microsoft/eslint-config-spfx@1.18.1 ├── @microsoft/eslint-plugin-spfx@1.18.1 ├── @microsoft/rush-stack-compiler-4.7@0.1.0 ├── @microsoft/sp-build-web@1.18.1 ├── @microsoft/sp-component-base@1.18.1 ├── @microsoft/sp-core-library@1.18.1 ├── @microsoft/sp-lodash-subset@1.18.1 ├── @microsoft/sp-module-interfaces@1.18.1 ├── @microsoft/sp-office-ui-fabric-core@1.18.1 ├── @microsoft/sp-property-pane@1.18.1 ├── @microsoft/sp-webpart-base@1.18.1 ├── @rushstack/eslint-config@2.5.1 ├── @types/react-dom@17.0.17 ├── @types/react@17.0.45 ├── @types/webpack-env@1.15.3 ├── ajv@6.12.6 ├── bindings@1.5.0 extraneous ├── eslint-plugin-react-hooks@4.3.0 ├── eslint@8.7.0 ├── file-uri-to-path@1.0.0 extraneous ├── gulp@4.0.2 ├── nan@2.18.0 extraneous ├── react-dom@17.0.1 ├── react@17.0.1 ├── tslib@2.3.1 └── typescript@4.7.4

Error in VS Code:

[12:14:42] [tsc] typescript version: 4.7.4 [12:14:43] Finished subtask 'copy-static-assets' after 2.12 s [12:14:53] Error - [tsc] src/webparts/spfxTestKhhaWebpart/components/SpfxTestKhhaWebpart.tsx(25,10): error TS7031: Binding element 'dispatch' implicitly has an 'any' type. [12:14:53] Error - [tsc] src/webparts/spfxTestKhhaWebpart/components/SpfxTestKhhaWebpart.tsx(25,25): error TS7006: Parameter 'next' implicitly has an 'any' type.[12:14:53] Error - [tsc] src/webparts/spfxTestKhhaWebpart/components/SpfxTestKhhaWebpart.tsx(25,33): error TS7006: Parameter 'action' implicitly has an 'any' type. [12:14:53] Error - [tsc] src/webparts/spfxTestKhhaWebpart/components/SpfxTestKhhaWebpart.tsx(67,22): error TS2339: Property 'checked' does not exist on type 'Readonly<{}>'. [12:14:53] Error - [tsc] src/webparts/spfxTestKhhaWebpart/components/SpfxTestKhhaWebpart.tsx(79,110): error TS2339: Property 'checked' does not exist on type 'Readonly<{}>'. [12:14:53] Error - [tsc] src/webparts/spfxTestKhhaWebpart/components/SpfxTestKhhaWebpart.tsx(89,129): error TS2339: Property 'checked' does not exist on type 'Readonly<{}>'. [12:14:53] Error - 'tsc' sub task errored after 11 s exited with code 2 [12:14:53] 'build' errored after 14 s [12:14:53] About to exit with code: 1 Process terminated before summary could be written, possible error in async code not continuing! Trying to exit with exit code 1

Update I already found a workaround to overrule tslint.config with

"noImplicitAny": false

But I still would like to know how I can fix it without the tslint rule.


Solution

  • The config of noImplicitAny, actually refers to the fallback TypeScript uses when there are no type annotations. This setting typically enables and disables whether TypeScript will throw error on fallbacks. You can check this in their documentation.

    In other words, even if you declare a variable with any type (e.g., dispatch: any), the error will immediately disappear as you have explicitly set it to any.

    Of course, you would always prefer to define the type as anything other than any, as it in some sense hinders the original intentions of using TypeScript, which is being type-safe.


    Let's talk about the code. There are two main problems in the question indeed, namely TS7031/TS3006 and TS2339.

    The second one is easier to solve. The problem is that you have extended the type of SpfxTestKhhaWebpart to React.Component<ISpfxTestKhhaWebpartProps, {}>, and {} is a read-only type, which is mentioned in the documentation:

    Tuples tend to be created and left un-modified in most code, so annotating types as readonly tuples when possible is a good default. This is also important given that array literals with const assertions will be inferred with readonly tuple types.

    Referencing the Microsoft TypeScript-React Conversion Guide, the second error should disappear if you set the type to React.Component<ISpfxTestKhhaWebpartProps, any>, which enables the use of calling the state from this specific React.Component typed class.


    The first one is more tricky, as you would have to set a correct type for all three variables: dispatch, next, and action, which would be hard for me to provide directly as I do not have the environment and cannot conduct test runs (most of the time by simply hover on or using console.log([target].constructor.name); could check the needed type).

    However, I most certainly believe this part:

    ({ dispatch }) => next => action => {[code_within]})
    

    Is, in fact, custom middleware configurations from libraries like redux, so you could check the parameters and return types of each original function - this middleware guide of redux could be a great start (assume you are using redux).

    That is all I could have thought of, but anyway a good question. Let me know if I could be of further assistance.