Skip to content

linter: react/button-has-type incorrectly flags document.createElement('button') #20938

@ahmedelgabri

Description

@ahmedelgabri

What version of Oxlint are you using?

1.58.0

What command did you run?

No response

What does your .oxlintrc.json (or oxlint.config.ts) config file look like?

{"plugins": ["react"], "rules": {"react/button-has-type": "error"}}

What happened?

react/button-has-type flags document.createElement('button') calls, which are DOM API calls and not React elements. ESLint's react/button-has-type only flags JSX <button> and React.createElement('button').

This is reproducible in the playground too

Root cause

is_create_element_call in crates/oxc_linter/src/utils/react.rs:21-32 matches any *.createElement() call by only
checking the property name, without verifying the object is React (or the configured pragma):

pub fn is_create_element_call(call_expr: &CallExpression) -> bool {
    match &call_expr.callee {
        Expression::StaticMemberExpression(member_expr) => {
            member_expr.property.name == "createElement"  // matches document.createElement too
        }
        // ...
    }
}

The test suite at line 344 of button_has_type.rs includes Foo.createElement("button") as a fail case, confirming
this is the current behavior. ESLint checks the object name against the configured React pragma (defaulting to React).

This utility is shared across multiple React rules, so fixing it may resolve similar issues in other rules too.

ESLint comparison

(trying to migrate from ESlint 7, hence why it's in the table)

Code ESLint 7 ESLint 10 oxlint
document.createElement('button') pass pass fail
React.createElement('button') fail fail fail
<button /> fail fail fail

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Priority

    None yet

    Effort

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions