Skip to content

Unsafe assignment allowed from a function union to a function type with rest parameters #62447

Closed as duplicate

Description

@HotariTobu

🔎 Search Terms

  • function union assign rest parameter
  • union of function signatures rest parameter
  • function union assignable to rest parameter
  • function overload union assign rest
  • function union parameter intersection rest assign
  • correlated union types
  • callable union parameter count
  • overload resolution union

🕗 Version & Regression Information

This is the behavior in every version I tried, and I reviewed the FAQ for entries about function union assignability and overload resolution.

⏯ Playground Link

https://www.typescriptlang.org/play/?ts=6.0.0-dev.20250913#code/C4TwDgpgBAYlC8UAUSCUCB8UB2BXAtgEYQBOU6APsksBAB7ABcUAzsCQJbYDm68WeIqVQAoAMYB7bGygAzZnEQ16wPlloMAdABsIPYAAsRI0JCgBxBMk02AhiW4tmbTjwDaAXTU4CxEuKkZbmZLRFljbjQRIA

💻 Code

type F = (() => number ) | ((text: string) => number)
const f: F = (text) => text.length

type G = (...args: string[]) => number
const g: G = f

g()

🙁 Actual behavior

No type error is reported on the assignment const g: G = f.

This allows a subsequent call g() which is type-safe according to G's signature. However, because the assigned implementation f requires an argument, this valid call leads to a runtime TypeError.

The type system is allowing an assignment that is demonstrably unsafe at runtime.

🙂 Expected behavior

A type error should be reported on the line const g: G = f.

The assignment should be disallowed because not all constituents of the union type F are safely assignable to the type G.

Specifically, the (text: string) => number member of F cannot be safely called with zero arguments, but the target type G explicitly allows being called with zero arguments. Therefore, the assignment creates a situation where a runtime error is inevitable if that code path is taken, which defeats the purpose of static type checking.

Additional information about the issue

I told Gemini to search known issues and found:

Activity

  1. jcalz commented on Sep 14, 2025

    @jcalz
    Contributor

    This has little to do with unions; you can expose the same unsoundness with

    type F = ((text: string) => number)

    As such this is a known and intentionally allowed unsoundness, and this issue is a duplicate of, say, #58552

  2. locked as resolved and limited conversation to collaborators on Nov 18, 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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions