1

I have a following definition of SRequest object:

type SRequest = {
  headers: string[];
  get(header: string): string;
  get(header: 'Set-Cookie'): string[];
}

const myReq: SRequest = {
  headers: [ 'a' ],
  get: (header: string | 'Set-Cookie'): string | string[] => {
    if (header === 'Set-Cookie') {
      return [ 'x' ];
    }
    return '';
  }
}

But it fails to compile. I thought with overloaded function I can use union type for different arguments but I get this error:

Error:

Type '(header: string | 'Set-Cookie') => string | string[]' is not assignable to type '{ (header: string): string; (header: "Set-Cookie"): string[]; }'.
  Type 'string | string[]' is not assignable to type 'string'.
    Type 'string[]' is not assignable to type 'string'.
3
  • I feel you are doing the whole overloading wrong. Function/method overload happens when each function or method has a different number of arguments but the same name, and the same return type. Yours violate the conditions. Commented Oct 20, 2022 at 9:05
  • The example provided is constrained on purpose, I'm actually trying to satisfy a compiler because such a definition is provided by external library. So it's probably issue with the definitions. However I think it's allowed to have different return type, see stackoverflow.com/a/24222144/3056783 Commented Oct 20, 2022 at 9:08
  • 1
    @KelvinUkuejubolaOritsetimeyi - that is not true. Function overloading in TypeScript allows different parameter and return types. This is more or less a common use case. Commented Oct 20, 2022 at 9:11

1 Answer 1

2

The TypeScript compiler only has limited ways of understanding function implementations. It basically just looks what the the type of each return statement is and creates a union of those types. In this case, that would result in string | string[] which conflicts with your overloads.

It probably feels like an unsatisfying solution, but forcefully silencing the error with an assertion might be the only way.

const myReq: SRequest = {
  headers: [ 'a' ],
  get: (header) => {
    if (header === 'Set-Cookie') {
      return [ 'x' ] as string & string[]
    }
    return '' as string & string[]
  }
}

The overload definition demands that the implementation must return a string and a string[] to satisfy both overloads; hence the interseciton. While not being truly type-safe, it would at least give some warnings when you would try to return a number for example.


Playground

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.