Skip to content

Hoc broken with [email protected] #111

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
belgattitude opened this issue Dec 3, 2018 · 15 comments · Fixed by #193
Closed

Hoc broken with [email protected] #111

belgattitude opened this issue Dec 3, 2018 · 15 comments · Fixed by #193
Labels
blocked upstream issue 🎁 Rewarded on Issuehunt This issue has been rewarded on Issuehunt IssueHunt

Comments

@belgattitude
Copy link

belgattitude commented Dec 3, 2018

Issuehunt badges

Got an issue with hoc and typescript 3.2.1, any idea of what's missing

Based on latest master:

https://github.com/piotrwitek/react-redux-typescript-guide/blob/master/playground/src/hoc/with-state.tsx

Tsc will fail with

hoc/with-state.tsx:41:18 - error TS2322: Type '{ count: number; onIncrement: () => void; }' is not assignable to type 'IntrinsicAttributes & WrappedProps & { children?: ReactNode; }'.
  Property 'count' does not exist on type 'IntrinsicAttributes & WrappedProps & { children?: ReactNode; }'.

Any ideas ?


IssueHunt Summary

piotrwitek piotrwitek has been rewarded.

Backers (Total: $50.00)

Submitted pull Requests


Tips


IssueHunt has been backed by the following sponsors. Become a sponsor

@piotrwitek
Copy link
Owner

piotrwitek commented Dec 3, 2018

@belgattitude thanks for report, there was a change with generic object spread, I need to investigate

Related:
microsoft/TypeScript#28884

@belgattitude
Copy link
Author

Thanks a lot...

I'm trying to figure out as well. If I find something I'll let you know.

Can be useful too: microsoft/TypeScript#28748

@IssueHuntBot
Copy link

@issuehuntfest has funded $20.00 to this issue. See it on IssueHunt

@jkillian
Copy link

jkillian commented Dec 11, 2018

Looks like the TypeScript team thinks this is a bug and is trying to fix it by next release:

image

Unfortunately, might mean it's difficult to fix from this side of things (though who knows, maybe there's a workaround)

@piotrwitek
Copy link
Owner

Thanks for heads-up @jkillian! I'll be tracking that one.

@WojciechMatuszewski
Copy link

Explanation and temporary solution

@piotrwitek
Copy link
Owner

Another related issue: microsoft/TypeScript#28884

@IssueHuntBot
Copy link

@IssueHunt has funded $30.00 to this issue.


@piotrwitek piotrwitek added blocked upstream issue and removed bug labels Apr 22, 2019
@zdila
Copy link

zdila commented Aug 23, 2019

I can't adjust types to use Redux connect. Is it related?

const tx = ...;

export type Translator = typeof tx;

interface InjectedProps {
  t: Translator;
}

export const withTranslator = <BaseProps extends InjectedProps>(
  _BaseComponent: React.ComponentType<BaseProps>,
) => {
  // fix for TypeScript issues: https://github.com/piotrwitek/react-redux-typescript-guide/issues/111
  const BaseComponent = _BaseComponent as React.ComponentType<InjectedProps>;

  type HocProps = Subtract<BaseProps, InjectedProps>;
  type TStateProps = ReturnType<typeof mapStateToProps>;

  class Hoc extends React.Component<HocProps> {
    static displayName = `injectL10n(${BaseComponent.name})`;
    static readonly WrappedComponent = BaseComponent;

    render() {
      const { ...restProps } = this.props;
      return <BaseComponent t={tx} {...restProps} />;
    }
  }

  const mapStateToProps = (state: RootState) => ({
    language: state.l10n.language,
  });
  
  // type error:
  return connect<TStateProps, {}, HocProps, RootState>(mapStateToProps)(Hoc);
};

Error:

Argument of type 'typeof Hoc' is not assignable to parameter of type 'ComponentType<Matching<{ language: string; } & DispatchProp<AnyAction>, Pick<BaseProps, SetDifference<keyof BaseProps, "t">>>>'.
  Type 'typeof Hoc' is not assignable to type 'ComponentClass<Matching<{ language: string; } & DispatchProp<AnyAction>, Pick<BaseProps, SetDifference<keyof BaseProps, "t">>>, any>'.
    Types of parameters 'props' and 'props' are incompatible.
      Type 'Matching<{ language: string; } & DispatchProp<AnyAction>, Pick<BaseProps, SetDifference<keyof BaseProps, "t">>>' is not assignable to type 'Readonly<Pick<BaseProps, SetDifference<keyof BaseProps, "t">>>'.
        Type 'P extends "dispatch" | "language" ? ({ language: string; } & DispatchProp<AnyAction>)[P] extends Pick<BaseProps, SetDifference<keyof BaseProps, "t">>[P] ? Pick<BaseProps, SetDifference<keyof BaseProps, "t">>[P] : ({ ...; } & DispatchProp<...>)[P] : Pick<...>[P]' is not assignable to type 'BaseProps[P]'.
          Type 'Pick<BaseProps, SetDifference<keyof BaseProps, "t">>[P] | (({ language: string; } & DispatchProp<AnyAction>)[P] extends Pick<BaseProps, SetDifference<keyof BaseProps, "t">>[P] ? Pick<...>[P] : ({ ...; } & DispatchProp<...>)[P])' is not assignable to type 'BaseProps[P]'.
            Type '({ language: string; } & DispatchProp<AnyAction>)[P] extends Pick<BaseProps, SetDifference<keyof BaseProps, "t">>[P] ? Pick<BaseProps, SetDifference<keyof BaseProps, "t">>[P] : ({ ...; } & DispatchProp<...>)[P]' is not assignable to type 'BaseProps[P]'.
              Type '({ language: string; } & DispatchProp<AnyAction>)[P] | Pick<BaseProps, SetDifference<keyof BaseProps, "t">>[P]' is not assignable to type 'BaseProps[P]'.
                Type '({ language: string; } & DispatchProp<AnyAction>)[P]' is not assignable to type 'BaseProps[P]'.
                  Type '{ language: string; } & DispatchProp<AnyAction>' is not assignable to type 'BaseProps'.
                    Type 'SetDifference<keyof BaseProps, "t"> extends "dispatch" | "language" ? ({ language: string; } & DispatchProp<AnyAction>)[("dispatch" & SetDifference<keyof BaseProps, "t">) | ("language" & SetDifference<...>)] extends Pick<...>[("dispatch" & SetDifference<...>) | ("language" & SetDifference<...>)] ? Pick<...>[("dispat...' is not assignable to type 'BaseProps[P]'.
                      Type '(({ language: string; } & DispatchProp<AnyAction>)[("dispatch" & SetDifference<keyof BaseProps, "t">) | ("language" & SetDifference<keyof BaseProps, "t">)] extends Pick<BaseProps, SetDifference<...>>[("dispatch" & SetDifference<...>) | ("language" & SetDifference<...>)] ? Pick<...>[("dispatch" & SetDifference<...>) ...' is not assignable to type 'BaseProps[P]'.
                        Type '({ language: string; } & DispatchProp<AnyAction>)[("dispatch" & SetDifference<keyof BaseProps, "t">) | ("language" & SetDifference<keyof BaseProps, "t">)] extends Pick<BaseProps, SetDifference<...>>[("dispatch" & SetDifference<...>) | ("language" & SetDifference<...>)] ? Pick<...>[("dispatch" & SetDifference<...>) |...' is not assignable to type 'BaseProps[P]'.
                          Type '({ language: string; } & DispatchProp<AnyAction>)[("dispatch" & SetDifference<keyof BaseProps, "t">) | ("language" & SetDifference<keyof BaseProps, "t">)] | Pick<BaseProps, SetDifference<...>>[("dispatch" & SetDifference<...>) | ("language" & SetDifference<...>)]' is not assignable to type 'BaseProps[P]'.
                            Type '({ language: string; }["dispatch" & SetDifference<keyof BaseProps, "t">] & DispatchProp<AnyAction>["dispatch" & SetDifference<keyof BaseProps, "t">]) | ({ language: string; }["language" & SetDifference<...>] & DispatchProp<...>["language" & SetDifference<...>])' is not assignable to type 'BaseProps[P]'.
                              Type '{ language: string; }["dispatch" & SetDifference<keyof BaseProps, "t">] & DispatchProp<AnyAction>["dispatch" & SetDifference<keyof BaseProps, "t">]' is not assignable to type 'BaseProps[P]'.
                                Type 'Pick<BaseProps, SetDifference<keyof BaseProps, "t">>[string] | Pick<BaseProps, SetDifference<keyof BaseProps, "t">>[number] | Pick<BaseProps, SetDifference<keyof BaseProps, "t">>[symbol]' is not assignable to type 'BaseProps[P]'.
                                  Type 'BaseProps[string]' is not assignable to type 'BaseProps[P]'.
                                    Type 'string' is not assignable to type 'P'.
                                      'string' is assignable to the constraint of type 'P', but 'P' could be instantiated with a different subtype of constraint 'string | number | symbol'.

Thanks.

@HQ92
Copy link

HQ92 commented Aug 26, 2019

I'm having the same issue as zdila. My Hoc using redux connect was working perfectly before I updated my typescript and redux packages. The code hasn't changed at all but I'm receiving these errors across all my Hocs which were built in exactly the same way.

I'm using:
"react": "^16.8.6",
"react-redux": "^7.1.0",
"redux": "^4.0.4",
"typescript": "^3.5.3",

@piotrwitek
Copy link
Owner

@zdila this issue is reproduced without connect, but potentially can be related.

@piotrwitek
Copy link
Owner

For issues with nested HOC using connect please use the following issue #5

@piotrwitek
Copy link
Owner

The issue is fixed using:

  {...(restProps as BaseProps)}

Full example:

import React from 'react';
import { Diff } from 'utility-types';

interface InjectedProps {
  count: number;
  onIncrement: () => void;
}

export const withState = <BaseProps extends InjectedProps>(
  BaseComponent: React.ComponentType<BaseProps>
) => {
  type HocProps = Diff<BaseProps, InjectedProps> & {
    initialCount?: number;
  };
  type HocState = {
    readonly count: number;
  };

  return class Hoc extends React.Component<HocProps, HocState> {
    static displayName = `withState(${BaseComponent.name})`;
    static readonly WrappedComponent = BaseComponent;

    readonly state: HocState = {
      count: Number(this.props.initialCount) || 0,
    };

    handleIncrement = () => {
      this.setState({ count: this.state.count + 1 });
    };

    render() {
      const { ...restProps } = this.props;
      const { count } = this.state;

      return (
        <BaseComponent
          count={count}
          onIncrement={this.handleIncrement}
          {...(restProps as BaseProps)} // <= HERE
        />
      );
    }
  };
};

piotrwitek added a commit that referenced this issue Nov 3, 2019
@piotrwitek
Copy link
Owner

@zdila I have added a solution for your issue in #5 and soon it will be added to the guide as a new section

piotrwitek added a commit that referenced this issue Nov 3, 2019
… recent TypeScript 3.7 and React & Redux type definitions. (#193)

* Updated deps

* Updated deps and refactored code to fix breaking changes

* Fixed issue with HOC Fixed #111

* Added an example of nested HOC with connect. Fixed #5

* Updated readme Intro & TOC

* Updated PR template

* Added new section with Nested HOC - wrapping a component, injecting props and connecting to redux #5

* Updated dev deps
@issuehunt-oss
Copy link

issuehunt-oss bot commented Nov 3, 2019

@piotrwitek has rewarded $35.00 to @piotrwitek. See it on IssueHunt

  • 💰 Total deposit: $50.00
  • 🎉 Repository reward(20%): $10.00
  • 🔧 Service fee(10%): $5.00

@issuehunt-oss issuehunt-oss bot added the 🎁 Rewarded on Issuehunt This issue has been rewarded on Issuehunt label Nov 3, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocked upstream issue 🎁 Rewarded on Issuehunt This issue has been rewarded on Issuehunt IssueHunt
Projects
None yet
7 participants