Skip to content

Type inference not working for React ref callback param #7088

Closed

Description

This looks like a type inference issue with tsc 1.8.0+ (also nightly), but I'm not sure. It could also be because of typings.

The offending code looks something like this:

// Inside React component
render() {
    return <Overlay ref={ref => this.overlayEl = ReactDOM.findDOMNode(ref) as HTMLElement} />;
    // error TS7006: Parameter 'ref' implicitly has an 'any' type.
}

I'm using ref "callback" syntax because the string-based syntax is deprecated by react and also not type safe. Needless to say, I have "noImplicitAny" enabled.

It looks like ref type is now an intersection between two types (relates to #5478), and the type inference no longer works, where previously it would be an instance of Overlay.

I can work around this issue for now by manually passing the type, like (ref: Overlay) =>, but it should work without it as well.

Activity

  1. RyanCavanaugh commented on Feb 16, 2016

    @RyanCavanaugh
    Member

    FWIW they say it's "legacy", not "deprecated", though in terms of their engineering cycle I have no idea what that means.

    If you don't mind diverging your react.d.ts file, I'd recommend changing the definition of ref by removing the string | part of it.

    The language-side fix here is non-React-specific, though -- when a function expression is contextually typed by a union type where exactly one of the constituents of the union has a call signature, we should use that type to contextually type the expression rather than giving up.

  2. RyanCavanaugh commented on Feb 16, 2016

    @RyanCavanaugh
    Member

    ... OK it turns out we already do that. I'll investigate what's going on.

  3. yuit commented on Jun 13, 2016

    @yuit
    Contributor

    already fix in master and latest nightly built Here is the scenario I tried using typing files from Types (@types)
    ref parameter of an error function is now inferred to be Overlay

    import * as React from "react"
    import * as ReactDOM from "react-dom"
    
    class Overlay extends React.Component<{}, {}> {
        render() {
            return <div> Overlay </div>
        }
    }
    class C extends React.Component<{}, {}> {
        overlayEl: HTMLElement;
        render() {
            return <Overlay ref={ref => this.overlayEl = ReactDOM.findDOMNode(ref) as HTMLElement} />;
        }
    }
    {
        "compilerOptions": {
            "noImplicitAny": true,
            "jsx": "react"
        }
    }
  4. locked and limited conversation to collaborators on Jun 19, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugA bug in TypeScriptFixedA PR has been merged for this issue

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions