preact icon indicating copy to clipboard operation
preact copied to clipboard

Preact 10.0.1 types not compatible with React-Redux 7.1.1?

Open AlexReff opened this issue 5 years ago • 8 comments

After setting noImplicitAny: true in my project, I realized I was missing the type declarations for react-redux. After running npm i -D @types/react-redux, I now get the following error on all of my components that use react-redux's connect

Argument of type 'typeof MY_COMPONENT' is not assignable to parameter of type 'ComponentType<never>'.
  Type 'typeof MY_COMPONENT' is not assignable to type 'ComponentClass<never, any>'.
    Types of property 'contextType' are incompatible.
      Type 'preact.Context<any>' is not assignable to type 'React.Context<any>'.
        Types of property 'Provider' are incompatible.
          Property '$$typeof' is missing in type 'Provider<any>' but required in type 'ProviderExoticComponent<ProviderProps<any>>'.ts(2345)
index.d.ts(318, 18): '$$typeof' is declared here. (Points to @types/react because of the dependency listed for @types/react-redux)
        "preact": "^10.0.1",
        "react-redux": "^7.1.1",
        "redux": "^4.0.4",
        "@types/react-redux": "^7.1.5",

Shortened example:

import { Component, h } from "preact";
import { connect } from "react-redux";

class MY_COMPONENT extends Component<IProps, IState> {
....
}

export default connect(mapStateToProps, mapDispatchToProps)(MY_COMPONENT); //error on MY_COMPONENT

I've googled this as much as I can and have not found any answers. I don't see $$typeof anywhere in Preact's index.d.ts file.

My tsconfig.json is:

{
    "compilerOptions": {
        "outDir": "./dist",
        "sourceMap": true,
        "noImplicitAny": true,
        "suppressImplicitAnyIndexErrors": true,
        "experimentalDecorators": true,
        "module": "commonjs",
        "target": "es6",
        "lib": [
            "es2015",
            "es2017",
            "dom"
        ],
        "allowJs": true,
        "removeComments": true,
        "allowSyntheticDefaultImports": true,
        "resolveJsonModule": true,
        "esModuleInterop": true,
        "jsx": "react",
        "baseUrl": "./",
        "jsxFactory": "h"
    },
    "exclude": ["node_modules", "dist", "deprecated"]
}

AlexReff avatar Oct 18 '19 23:10 AlexReff

How about trying to use preact-redux? https://github.com/developit/preact-redux

38elements avatar Oct 23 '19 00:10 38elements

If you're using Preact X (preact@10+), please use the official react-redux library.

AlexReff avatar Oct 23 '19 15:10 AlexReff

Update: it looks as though the core issue might be the type definition of @types/react-redux's connect function.

I have not encountered any actual functional bugs outside of this type 'mismatch'

See: https://github.com/DefinitelyTyped/DefinitelyTyped/issues/19989

Workarounds:

If you still need other typings for react-redux, just cast as any wherever needed.

Otherwise,

A) set noImplicitAny to false in your tsconfig.json

or

B) create a declarations.d.ts file with the line declare module "react-redux"; in it, and remove @types/react-redux entirely.

AlexReff avatar Nov 08 '19 16:11 AlexReff

How about trying to use preact/compat?

38elements avatar Nov 15 '19 16:11 38elements

I don't believe there is a connect function exported in preact/compat - and using Component from preact/compat doesn't change this outcome. I think the issue lies with @types/react-redux and not with preact itself.

AlexReff avatar Nov 19 '19 16:11 AlexReff

Have you tried aliasing react to preact in the typescript config as well?

ForsakenHarmony avatar Nov 20 '19 01:11 ForsakenHarmony

Can confirm that @ForsakenHarmony's suggestion works. Your tsconfig should look a little something like this:

{
  "compilerOptions": {
    // ...
    "baseUrl": ".",
    "paths": {
      "react": ["node_modules/preact/compat"],
      "react-dom": ["node_modules/preact/compat"]
    }
  }
}

birjj avatar Mar 30 '20 11:03 birjj

      import * as Preact from 'https://unpkg.com/preact?module'
      import htm from 'https://unpkg.com/htm?module'
      const html = htm.bind(Preact.createElement)

      import * as reactRedux from 'https://unpkg.com/react-redux?module'

Is something like this possible? (no typescript, no rollup, etc.)

https://github.com/preactjs/preact/issues/3469

brandonros avatar Mar 01 '22 06:03 brandonros