Definitelytyped: @types/react and @types/react-dom type 'Element' is not assignable to type 'ReactElement<any>[]'

Created on 2 Aug 2018  路  28Comments  路  Source: DefinitelyTyped/DefinitelyTyped

I have this simple code:

import * as React from "react";
import * as ReactDOM from "react-dom";

ReactDOM.render(<div>Hi</div>, document.getElementById("root"));

that is giving me this error:

Argument of type 'Element' is not assignable to parameter of type 'ReactElement<any>[]'.
  Property 'length' is missing in type 'Element'.

I've currently tried these versions of react and react-dom:

"react": "16.4.2",
"react-dom": "16.4.2",
"@types/react": "16.4.7",
"@types/react-dom": "16.0.6",

and

"react": "16.4.0",
"react-dom": "16.4.0",
"@types/react": "16.3.17",
"@types/react-dom": "16.0.6",

I'd like to have react 16, but I'm not sure what the typing issue is here.

Most helpful comment

Argument of type 'Element' is not assignable to parameter of type '(prevState: null) => null'. Type 'Element' provides no match for the signature '(prevState: null): null'.

still exists..

All 28 comments

I am having a similar issue here. Is this new desired behavior?

Started to appear on:

{
  "@types/react": "16.4.8"
}

All version prior to recent update didn't give any errors.

__EDIT:__

Removed @types/react-dom, since it's an issue with @types/react.

export const T: SFC<{}> = ({ }) => {
  return (<div />);
}

gives

Type '({}: { children?: ReactNode; }) => Element' is not assignable to type 'StatelessComponent<{}>'.
  Type 'Element' is not assignable to type 'ReactElement<any>'.

Fixed by downgrading to 16.4.7

UPDATED: Actually just removing the LibraryManagedAttributes type fixes the problem
https://github.com/DefinitelyTyped/DefinitelyTyped/commit/1d9679b2dcf7c9643d623b626c0820f84eaa8d7e#diff-96b72df8b13a8a590e4f160cbc51f40cR2309

I'm not sure what LibraryManagedAttributes are, or why'd they'd break existing code.

It looks like this is the change from #27901 causing the problem
https://github.com/DefinitelyTyped/DefinitelyTyped/commit/1d9679b2dcf7c9643d623b626c0820f84eaa8d7e#diff-96b72df8b13a8a590e4f160cbc51f40cL2208-L2230

@ferdaber any idea what's going on here?

@cdeutsch Unsure of why it would break, but LibraryManagedAttributes are part of the defaultProps support in TS3

@jonathanhuang13 what version of TS are you using?

If anyone can give a full example or a minimally reproducible repo that would be great. With LibraryManagedAttributes, the static properties of a component affects type checking when that component is used in a JSX expression, but it shouldn't affect any intrinsic components like div or span, only value based components.

I am unable to reproduce it with TS 3.0.

My issue may actually be different then @jonathanhuang13 (repro at the end)

Yes, I'm using TS 3.0

@jonathanhuang13 your issue could be multiple versions of @types/react installed by yarn.lock.

Make sure your yarn.lock doesn't look like this (2 different versions)

"@types/react@*":
  version "16.0.38"
  resolved "https://registry.yarnpkg.com/@types/react/-/react-16.0.38.tgz#76617433ea10274505f60bb86eddfdd0476ffdc2"

"@types/[email protected]":
  version "16.4.8"
  resolved "https://registry.yarnpkg.com/@types/react/-/react-16.4.8.tgz#ff0440429783df0927bdcd430fa1225f7c08cf36"
  dependencies:
    "@types/prop-types" "*"
    csstype "^2.2.0"

I just manually edit it to be this (and then it works until something touches @types/react again):

"@types/react@*", "@types/[email protected]":
  version "16.4.8"
  resolved "https://registry.yarnpkg.com/@types/react/-/react-16.4.8.tgz#ff0440429783df0927bdcd430fa1225f7c08cf36"
  dependencies:
    "@types/prop-types" "*"
    csstype "^2.2.0"

Yarn has a duplicate dependency issue that will likely never be fixed (I'm working on switching back to npm)
https://github.com/yarnpkg/yarn/issues/3967


Repro of my issue

https://github.com/cdeutsch/LibraryManagedAttributes-Repro/

When I try use an antd Input I get the following error:

(7,6): Type '{ autoFocus: true; }' is not assignable to type 'Pick, InferProps<{ type: any; id: any; size: any; maxLength: any; disabled: any; value: any; defaultValue: any; className: any; addonBefore: any; ... 9 more ...; suffix: any; }>>, "max" | ... 281 more ... | "suffix">'.
Property 'autosize' is missing in type '{ autoFocus: true; }'.

I'm guessing it's because of these typings, but I don't understand how/why propTypes is making autosize required

export default class Input extends React.Component<InputProps, any> {
    static Group: typeof Group;
    static Search: typeof Search;
    static TextArea: typeof TextArea;
    static defaultProps: {
        prefixCls: string;
        type: string;
        disabled: boolean;
    };
    static propTypes: {
        type: any;
        id: any;
        size: any;
        maxLength: any;
        disabled: any;
        value: any;
        defaultValue: any;
        className: any;
        addonBefore: any;
        addonAfter: any;
        prefixCls: any;
        autosize: any;
        onPressEnter: any;
        onKeyDown: any;
        onKeyUp: any;
        onFocus: any;
        onBlur: any;
        prefix: any;
        suffix: any;
    };
    input: HTMLInputElement;
    handleKeyDown: (e: React.KeyboardEvent<HTMLInputElement>) => void;
    focus(): void;
    blur(): void;
    getInputClassName(): any;
    saveInput: (node: HTMLInputElement) => void;
    renderLabeledInput(children: React.ReactElement<any>): React.ReactElement<any>;
    renderLabeledIcon(children: React.ReactElement<any>): React.ReactElement<any>;
    renderInput(): React.ReactElement<any>;
    render(): React.ReactElement<any>;
}

Here's the original Ant Design Input.tsx

https://github.com/ant-design/ant-design/blob/f2ce60cb6ccd79b89c63ba01c98de953013db51c/components/input/Input.tsx

@ferdaber I was using TS 3.0.1.

I wonder if my issues is a bug with TypeScript and the new LibraryManagedAttributes feature itself.

I can't replicate the issue if I recreate the Ant Design <Input> using .tsx

But when TS, uses the Input.d.ts of the NPM package, I get the error:

Type '{}' is not assignable to type 'Pick, InferProps<{ type: any; id: any; size: any; maxLength: any; disabled: any; value: any; defaultValue: any; className: any; addonBefore: any; ... 9 more ...; suffix: any; }>>, "children" | ... 281 more ... | "autosize">'.
Property 'autosize' is missing in type '{}'.

https://github.com/cdeutsch/LibraryManagedAttributes-Repro/commit/2332ee24829d8843e11b58458aed19143b4e6075#diff-38682f47b0cf12c516bc3714fc45d0fdR10

I see the problem, Input.d.ts is causing LibraryManagedAttributes to go awry because it's poorly typed:

class Input extends React.Component<InputProps> {
  static propTypes: {
    type: any
    id: any
    size: any
    /* ... */
  }
}

The any type is causing autosize to be a required property, it's an interesting resolution. The fix would be for Input.d.ts to have this for propTypes:

class Input extends React.Component<InputProps> {
  static propTypes: PropTypes.ValidationMap<InputProps>
}

I will continue to try troubleshooting why the LibraryManagedAttributes resolution is failing on poorly-typed propTypes.

Thanks @ferdaber. I appreciate you taking the time to help 馃憤

I'll pass that info on to Ant Design

@ferdaber ,

I have a question about type LibraryManagedAttributes.

All props defined in propTypes are optional. That is the default from library prop-types. Why do we need to infer types from propTypes in LibraryManagedAttributes? The TypeScript doesn't transpile them into optional. That is the poor typed case in Input.d.ts.

The line below see merge the props from propTypes

https://github.com/DefinitelyTyped/DefinitelyTyped/blob/b8d4502de5dfd1f128f5b2c4fad074a6397449e8/types/react/index.d.ts#L2313

LibraryManagedAttributes is the new feature in TS 3.0 that allows the compiler to infer assignable JSX attributes to value-based components via static properties assigned to that value-based component.

Technically it doesn't need to use the propTypes property to infer props (it's greatest use case for actual TS users is the optionalizing of props defined in defaultProps), however I added the inference of propTypes to also allow JS users to be able to take advantage of propTypes to get IntelliSense on their JSX without needing JSDoc annotations.

As to why it's optional vs required, LibraryManagedAttributes should be able to correctly set inferred prop types as optional if it were properly set:

declare const Foo: React.Component // unannotated component
Foo.propTypes = {
  foo: PropTypes.string,
  bar: PropTypes.bool.isRequired
}

const foo = <Foo /> // <-- LibraryManagedAttributes will make 'bar' required and 'foo' optional

@ferdaber thank you very much for your detailed explaination. I agree that TS users would utlize react defaultProps for stronger types checking since TS 3.0.

Let's go back to the issue reported from Ant Design. React Components of Ant Design are developed using TypeScripts. Their .d.ts files seems be generated through tsc --decaration. As a result, propTypes lose its original PropTypes information and turns into any.

Ant Design releases transipled js and related d.ts decaration files to npm registry. As TS user of Ant Design, LibraryManagedAttributes is breaking the TypeScript type checks because Ant Desing's .d.ts has any in PropTypes unless we override their type defintion in our own project using what your mentioned above.

It seems that Ant Design should consider to have their d.ts defined seperately or maintain a version of @types/antd here in DefinitelyTyped repo.

@aaronchenwei either define .d.ts separately, or maybe try regenerating the declaration files. I believe that if the dependency on @types/prop-types for Ant Design is upgraded to the latest version, the generated types for Component.propTypes should be correct (instead of generating any), if not, it may be an actual issue with TS itself.

I have created a minimal reproduction for a Gatsby project.

https://github.com/azdanov/gatsby-type

This line shows up as an error on latest @types/react:

https://github.com/azdanov/gatsby-type/blob/e522449717a38dca79671e888af278eb0a2cdfaa/src/pages/index.tsx#L3

So I ran into a similar issue. I've gotten the following two errors after a fresh install and start

/Users/nicholas/Development/node_modules/@types/react/index.d.ts
(2310,14): Duplicate identifier 'LibraryManagedAttributes'.

and

/Users/nicholas/Development/cra-lib/node_modules/@types/react/index.d.ts
(2303,19): Interface 'Element' cannot simultaneously extend types 'ReactElement<any>' and 'ReactElement<any>'.
  Named property 'type' of types 'ReactElement<any>' and 'ReactElement<any>' are not identical.

To reproduce, run

create-react-app testing --scripts-version=react-scripts-ts

cd testing

yarn start

You'll get:

/Users/nicholas/Development/node_modules/@types/react/index.d.ts
(2310,14): Duplicate identifier 'LibraryManagedAttributes'.

This is with package.json looking like:

{
  "name": "cra-lib",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "react": "^16.4.2",
    "react-dom": "^16.4.2",
    "react-scripts-ts": "2.17.0"
  },
  "scripts": {
    "start": "react-scripts-ts start",
    "build": "react-scripts-ts build",
    "test": "react-scripts-ts test --env=jsdom",
    "eject": "react-scripts-ts eject"
  },
  "devDependencies": {
    "@types/jest": "^23.3.1",
    "@types/node": "^10.7.0",
    "@types/react": "^16.4.10",
    "@types/react-dom": "^16.0.7",
    "typescript": "^3.0.1"
  }
}

To get rid of the error, switch your @types/react to

"@types/react": "16.4.9",

rm -rf node_modules

rm yarn.lock

npm install

npm start

You should start up just fine.

If you try doing this process (deleting your node_modules and yarn.lock files and reinstalling) with yarn instead of node, you'll have duplicate @types/react in your yarn.lock

"@types/react@*":
  version "16.4.10"
  resolved "https://registry.yarnpkg.com/@types/react/-/react-16.4.10.tgz#fb577091034b25a81f829923e7d38258f43e3165"
  dependencies:
    "@types/prop-types" "*"
    csstype "^2.2.0"

"@types/[email protected]":
  version "16.4.9"
  resolved "https://registry.yarnpkg.com/@types/react/-/react-16.4.9.tgz#98b4dba5a0419dbd594f5dbbb2479e1e153431bb"
  dependencies:
    "@types/prop-types" "*"
    csstype "^2.2.0"

and get this error

/Users/nicholas/Development/testing/node_modules/@types/prop-types/node_modules/@types/react/index.d.ts
(2303,19): Interface 'Element' cannot simultaneously extend types 'ReactElement<any>' and 'ReactElement<any>'.
  Named property 'type' of types 'ReactElement<any>' and 'ReactElement<any>' are not identical.

Ok something funky must be going on here with create react app. I just realized there was a node_modules folder in my development folder (folder which holds all projects). Somehow, that got created and my testing applications i was creating above were referencing those node_modules and it's own at different times.

I deleted that folder and everything works just fine.

I'm pretty confused as to what happened, but I can no longer reproduce those issues I kept running into above.

Argument of type 'Element' is not assignable to parameter of type '(prevState: null) => null'. Type 'Element' provides no match for the signature '(prevState: null): null'.

still exists..

@yanlee26 that error message is unrelated to any of the ones posted above, can you add more context, or open a new issue?

error :

     TS2605: JSX element type '(Element | undefined)[]' is not a constructor function for JSX elements.
  Type '(Element | undefined)[]' is missing the following properties from type 'Element': type, props, key

code :

function renderOneCriteria(
  props: Props,
  criterion: Criterion<CriterionValue> | undefined,
  ix: number,
  criteria: Criterion<CriterionValue>[],
  ) {
  // [...]
  return <>
    <CriteriaInput
      criterion={criterion}
      allFields={allFields}
      disabled={props.disabled ? props.disabled : false}
      updateCriterionField={updateCriterionField(ix)}
      updateCriterionOperator={updateCriterionOperator(ix)}
      updateCriterionSingleValue={updateCriterionSingleValue(ix)}
      updateCriterionValues={updateCriterionValues(ix)}
      fieldError={getError(ix, 'field')}
      operatorError={getError(ix, 'operator')}
      valuesError={getError(ix, 'values')}
    />,
    criterion && <Delete key="delete" className={commonStyles.actionIcon} onClick={dropCriterion(ix)} />
  </>
}

libraries versions :
"@types/react": "16.8.22",
"@types/react-dom": "16.8.4",

This error usually means that you returned an array of elements instead of just a simple element in your component-- which the compiler doesn't like. React allows you to return arrays, but in TypeScript you'd need to assert it as any first.

I had the original problem

Element' is not assignable to type 'ReactElement[]

But don't see it anymore with @types/[email protected]

Can someone confirm that this is fixed and this issue may be closed?

The problem still exists in @types/[email protected]. Only updating the type to any as stated by @ferdaber resolves the issue, not sure this is a correct behavior for ts though.

I removed @types/react from my deps and it started working. It is the dep of @types/react-dom and the duplicate imports were causing conflicts. It still appears in my yarn.lock and works

I am running to a similar issue:

TS2300: Duplicate identifier 'LibraryManagedAttributes'.
node_modules/@types/react/index.d.ts (2953:14)

2953         type LibraryManagedAttributes<C, P> = C extends React.MemoExoticComponent<infer T> | React.LazyExoticComponent<infer T>
                  ~~~~~~~~~~~~~~~~~~~~~~~~

  ../../node_modules/@types/react/index.d.ts:2963:14
    2963         type LibraryManagedAttributes<C, P> = C extends React.MemoExoticComponent<infer T> | React.LazyExoticComponent<infer T>
                      ~~~~~~~~~~~~~~~~~~~~~~~~
    'LibraryManagedAttributes' was also declared here.
Was this page helpful?
0 / 5 - 0 ratings