Answer the question
In order to leave comments, you need to log in
Why is function overloading needed?
I do not really understand the expediency of using overload.
The tutorial says that this is necessary so that the function can accept different types of data and return different types of data. And this is an example:
type Reserve = {
(from: Date, to: Date, destination: string): string
(from: Date, destination: string)
}
const reserve: Reserve = (
from: Date,
toOrDestination: Date | string,
destination?: string
) => {
if (toOrDestination instanceof Date && destination !== undefined) {
return 'Round way ticket'
} else if (typeof toOrDestination === 'string') {
return 'One way ticket'
}
}
type Reserve2 = (from: Date, destination: string, to?: Date) => string
const reserve2: Reserve2 = (from, dest, to) => (
!to ? 'One way ticket' : 'Round way ticket'
)
type SumOrConcat = {
(a: number, b: number): number
(a: string, b: number): string
}
const result: SumOrConcat = (a: any, b: any): any => {
if (typeof a === 'number') {
return a + b
}
return `${a} ${b}`
}
type SumOrConcat = (a: number | string, b: number) => number | string
const result: SumOrConcat = (a, b) => (
typeof a === 'number' ? a + b : `${a} ${b}`
)
Answer the question
In order to leave comments, you need to log in
Overloads are needed in the following cases:
1. When the type of the returned value depends on the type of some argument;
2. When the types of subsequent arguments depend on the type of some argument;
3. Combination of 1 and 2 options.
It is important to understand that in TS overloads exist only at the type level, unlike in other languages. Moreover, the overloads themselves are implemented as an intersection from all signatures, which sometimes causes problems with assigning a function to a type with an overloaded signature. It's all about variance, since the function arguments are contravariant to the signature of the function itself, when most type relations (including intersection) in TS are covariant. In your SumOrConcat example, this problem was solved by using the any type, which makes any composition of types with it bivariant.
In fact, in the example with SumOrConcat, it is quite possible to set types to the arguments:
type SumOrConcat = {
(a: number, b: number): number
(a: string, b: number): string
}
const result: SumOrConcat = (a: number | string, b: number): any => {
if (typeof a === 'number') {
return a + b
}
return `${a} ${b}`
}
But it's safer like this:type SumOrConcat = {
(a: number, b: number): number
(a: string, b: number): string
}
const result = ((a: number | string, b: number): number | string => {
if (typeof a === 'number') {
return a + b
}
return `${a} ${b}`
}) as SumOrConcat;
Well, it should be noted that the syntax of the overloads themselves does not have such problems, although you cannot describe an arrow function with itfunction sumOrConcat(a: number, b: number): number;
function sumOrConcat(a: string, b: number): string;
function sumOrConcat(a: number | string, b: number): number | string {
if (typeof a === 'number') {
return a + b
}
return `${a} ${b}`
}
const result = sumOrConcat;
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question