Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React and typescript with webpack typing issue

I'm trying to create an asyncComponent higher order component with TypeScript, but can't quite get the types right.

Essentially, this works in JS with webpack...

const Auth = asyncComponent(() =>
  require.ensure([], require => require("../auth/index").default, "auth_async"),
);

My asyncComponent is a higher order function that does the following...

import * as React from "react";
import { Component } from 'react';

export interface IAsyncComponentProps {}

export interface IAsyncComponentState {
  Component: typeof Component
}

interface IGetComponent {
  (): Promise<typeof Component>;
}

export default function asyncComponent (getComponent: IGetComponent) {
  let ComponentCache: typeof Component = null;

  return class AsyncComponent extends Component<IAsyncComponentProps, IAsyncComponentState> {
    state: {
      Component: typeof Component,
    };

    constructor(props: IAsyncComponentProps) {
      super(props);
      this.state = { Component: ComponentCache };
    }

    componentWillMount() {
      if (!this.state.Component) {
        getComponent().then((Component) => {
          ComponentCache = Component;

          this.setState({ Component });
        });
      }
    }
    render() {
      const { Component } = this.state;

      if (Component) {
        return <Component {...this.props} />;
      }
      return null;
    }
  };
}

But, I get an error when compiling it...

src/components/asyncComponent/index.tsx(40,27): error TS2322: Type '{ children?: ReactNode; }' is not assignable to type 'IntrinsicAttributes & IntrinsicClassAttributes<Component<P, S>> & Readonly<{ children?: ReactNode...'.
  Type '{ children?: ReactNode; }' is not assignable to type 'Readonly<P>'.
src/index.ts(3,7): error TS1141: String literal expected.
11:06:50 AM - Compilation complete. Watching for file changes.

Any ideas?

like image 823
jcreamer898 Avatar asked Apr 28 '17 16:04

jcreamer898


1 Answers

I will try my best to explain what went wrong and how it got solved in the latest release of typescript.

Reason:

The reason for change in behavior is that in 2.3, Similar to object literal expression which contains freshness flag, JSXAttributes are type-check too(this means that excess properties are not allowed)

Solution Proposed: - Refer the Reference link

  1. Only contain explicitly attributes -> no excess properties allowed
  2. Contain spread attributes (even with explicit attributes) -> 1. check type assignability (allow access properties) 2. for each explicit attributes check if the attribute name match the target name.

This issue is being apparently solved in 2.3.3 latest stable version and 2.4.0 dev as well.

Use npm install typescript@next for the nightly build that is 2.4.0 dev or update the typescript version to latest stable(2.3.3)

Reference : Issuse Tracker

like image 197
Keshan Nageswaran Avatar answered Oct 21 '22 14:10

Keshan Nageswaran