Skip to content

preact/compat is incompatible with @types/react #4908

@remcohaszing

Description

@remcohaszing
  • Check if updating to the latest Preact version resolves the issue

Describe the bug
The types of preact/compat conflict with React.

There are a couple of issues at play leading to type conflicts between React and Preact.

  • React 19 removed the UMD bundle.
  • Yet the for the types for the UMD bundle are preserved in version 19. (Not sure why my comment was marked off-topic.)
  • Preact also declares types for the global React UMD bundle.
  • The global UMD React namespaces from @types/react and preact/compat get merged.
  • When you configure TypeScript with the jsx option set to preserve or react, it uses the JSX namespace defined by the jsxFactory option. The default value of React.createElement means you use the React.JSX namespace available in the file. This namespace can be made available globally, by importing React, or by declaring it locally.
    • If you set the jsx option to react-jsx, you use the JSX namespace of the automatic runtime. There are no problems.
  • If you set the jsx option to preserve or react and import preact/compat anywhere in your project, you get this error for any JSX children.
    file.tsx:6:5 - error TS2322: Type 'Element' is not assignable to type 'ReactNode'.
      Property 'children' is missing in type 'VNode<any>' but required in type 'ReactPortal'.
    
    6     return (
          ~~~~~~
    
      node_modules/@types/react/index.d.ts:388:9
        388         children: ReactNode;
                    ~~~~~~~~
        'children' is declared here.
  • If you set the the jsx option to react, you get the following additional error for all JSX elements. Resolving this error will also resolve the problem above
    file.tsx:7:10 - error TS2686: 'React' refers to a UMD global, but the current file is a module. Consider adding an import instead.
    
    7         <div>
               ~~~
    

I use Next.js and pulled in Preact as a transient dependency. Next.js (incorrectly) forces you to set jsx to preserve.

To Reproduce

If possible, please provide a link to a StackBlitz/CodeSandbox/Codepen project or a GitHub repository that demonstrates the issue. You can use the following template on StackBlitz to get started: https://stackblitz.com/edit/create-preact-starter

Steps to reproduce the behavior:

  1. Clone https://github.com/remcohaszing/preact-typescript-issue
  2. Run npm ci
  3. Run npx tsx, or play around with an editor

Expected behavior
No type errors.

I would like to help think of a solution, but I first need to understand this need for augmentation. My gut feeling tells me 2 changes should be made:

  1. VNode should specify children
  2. preact/compat should not declare the React UMD namespace. It should augment react instead.

Refs vercel/next.js#83159

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions