Skip to content

never cannot be spread into object, but it can be spread into JSX propsΒ #48556

Closed

Description

@knpwrs

Bug Report

πŸ”Ž Search Terms

  • props
  • never
  • spread

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about jsx, never, and spreads. This seems like a design limitation.

⏯ Playground Link

Playground link with relevant code

πŸ’» Code

// @ts-ignore
const obj: never = {}

const obj2 = {...obj}
const el = <div {...obj} />

πŸ™ Actual behavior

As seen in kiliman/remix-params-helper#19, never is able to be spread into JSX props, even though never cannot be spread into objects. This seems odd to me as both compile to Object.assign. See screenshots:

TypeScript prevents spreading never into an object:

image

But spreading never into props works fine:

image

πŸ™‚ Expected behavior

never should be prevented from spreading into jsx props, just like it cannot be spread into objects.

Activity

  1. Josh-Cena commented on Apr 15, 2022

    @Josh-Cena
    Contributor

    I wish spreading never is allowedβ€”if anything it should be allowed in objects as well.

    never extends object or any object type, so from a soundness perspective, I don't think this is unsafe. If it is compiled to Object.assign({}, obj), then obj being never is also fine because it's simply a top-type in parameter. From an ergonomics perspective, I often use ...(props as never) in cases where TS can't reason the type properly, like a simple polymorphic component:

    function Comp<T extends "div" | "pre">({
      as: As,
      ...props
    }: { as: T } & React.ComponentProps<T>) {
      return <As {...(props as never)} />
    }

    The never here reads well to me because props can be naturally seen as function parameters in the context of functional components. If never is disallowed here, I'd have to do (props as any), which is undesirable because (a) it's less safe (though not so much) compared to never and (b) it's banned by ESLint for good reason and I don't want to disable it for this particular case.

  2. locked as resolved and limited conversation to collaborators on Oct 22, 2025
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 TypeScriptHelp WantedYou can do this

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions