Skip to content

Overloaded arrow function requires any param, function syntax accepts union #37824

Closed
@cayhorstmann

Description

@cayhorstmann

TypeScript Version: 3.8.3

Search Terms:
Overloading, arrow functions, type union, any
Code

const remove: {
  (str: string, c: string): string
  (str: string[], c: string): string[]
} = (str: string | string[], c: string) =>{
  if (Array.isArray(str))
    return str.map(s => s.replace(c, ''))
  else
    return str.replace(c, '')
}

Expected behavior:

Either the function compiles, or the version with function also fails to compile

function remove2(str: string, c: string): string
function remove2(str: string[], c: string): string[]
function remove2(str: string | string[], c: string) {
  if (Array.isArray(str))
    return str.map(s => s.replace(c, ''))
  else
    return str.replace(c, '')
}

Actual behavior:

The following error occurs with the arrow version:

  Type 'string | string[]' is not assignable to type 'string'.
  Type 'string[]' is not assignable to type 'string'.(2322)

I must change the parameter of the implementation from string | string[] to any for the code to compile.

However, the version with function compiles.

Playground Link:

Playground link

Related Issues:

Note that this is subtly different from #33482 where the return type of the implementing function was questioned. Here, no return type is specified. The issue is the parameter type.

I understand the error message. Instead of looking at the behavior of the function, it is simply stated that (str: string | string[], c: string) => string | string[] is not compatible with the LHS type. That is undispably the case.

However, the function overload traces the function behavior, finding that string arguments lead to string return values and string[] arguments to string[] return values. The same could be done here: when the LHS is typed as an overload and the RHS is a literal arrow function, check whether the particular instance (and not any instance with that type) is assignable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    QuestionAn issue which isn't directly actionable in code

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions