Typescript: TSX spread stopped working

Created on 16 Feb 2017  ·  10Comments  ·  Source: microsoft/TypeScript

import * as React from "react";

interface Props {

}

export class Test extends React.Component<Props, {}> {
    render() {
        return <div {...this.props} />
    }
}

Was working fine until: [email protected]

In [email protected] throws:

error TS2698: Spread types may only be created from object types.

Not sure if related: https://github.com/Microsoft/TypeScript/issues/13557

Bug JSTSX Fixed

Most helpful comment

JSX spread is very common; this needs to work for a major release

Is there a workaround for folks wanting to use ts 2.3 with spread types? It seems like the common react pattern of spreading this.props will no longer work. Example code:

class Component<T extends object> extends React.Component<T, {}> {
  render() { return <div { ...this.props }></div>; }
}

compiler output:

ERROR in ./file.tsx
(34,17): error TS2698: Spread types may only be created from object types.

All 10 comments

@normalser it is related to #13557 as now spread operation in Jsx is going through same logic as normal spread (previously it is handled separately... I will discuss with @sandersn who is working in this area

It will be fixed by #13288. Reviews are welcome!

The original proposal is #10727, which is the main bug for this issue.

In #13288, getSpreadType has a special case that flattens intersections if they only contain object types (no type parameters, etc). I don't know React, but spreading this.props looks like it is extremely common. If so, it would be worthwhile to ship that part of the change early.

@normalser @yuit @RyanCavanaugh opinions from people who actually know React?

Note that this would make error reporting a lot harder (impossible?) for the case that the intersection does contain a type parameter.

After discussing with @yuit, I think the fix is just to get #13288 checked in soon so that spread types are fully supported. Supporting intersections separately would be too error-prone.

Well, it turns out that the culprit is that checkObjectLiteral and createJsxAttributesType both call getSpreadType and both check for object types. But createJsxAttributesType doesn't call isValidSpreadType, it uses an older, simpler check. So this is an easy fix, after all: just make anybody who calls getSpreadType first call isValidSpreadType.

JSX spread is very common; this needs to work for a major release

Fix is up at #14122

JSX spread is very common; this needs to work for a major release

Is there a workaround for folks wanting to use ts 2.3 with spread types? It seems like the common react pattern of spreading this.props will no longer work. Example code:

class Component<T extends object> extends React.Component<T, {}> {
  render() { return <div { ...this.props }></div>; }
}

compiler output:

ERROR in ./file.tsx
(34,17): error TS2698: Spread types may only be created from object types.

@stephen we are going to take a look about this and see what we can do. We have this PR (https://github.com/Microsoft/TypeScript/pull/13288/files) for normal spread which we will want to get in and apply for React

Update we have lifted up the restriction.... The fix is in tonight nightly. we will also ship this for 2.3.3

Was this page helpful?
0 / 5 - 0 ratings