Home > Mobile >  How to restrict the generic T of add (a: T, b: T):T in typescript so that it is either a and b are s
How to restrict the generic T of add (a: T, b: T):T in typescript so that it is either a and b are s

Time:01-14

Functions can be defined in js as follows:

function add(a, b) {return a b}

Then it is allowed to call as follows:

add(1, 2)

add('hello', 'world')

However, it is not allowed to call:

add(1, 'world')

add('hello', 2)

The following code cannot meet the above requirements:

function(a:string|number, b:string|number):string|number {return a b}

How to implement the same code in typescript ?

CodePudding user response:

I find this question interesting because this might be a legitimate limitation of TypeScript.

The obvious solution of simply returning a b does not work, TypeScript complains that T T can not be operated on despite what that we know a and b must be either string or number and both those types are valid in a concatenation or addition operation.

Thus, I bring you, without any casting, a solution to this problem:

function add<T extends string | number>(a: T, b: T): T {
  return Array.from(arguments).reduce((t, c) => t   c);
}

console.log(add("Hello", " World!")); // "Hello World!"
console.log(add(4, 3)); // 7
add("Foo", 1337); // Error

Playground

It should be noted this is a sort of hack, arguments produces any[] and is only available in non arrow functions.

CodePudding user response:

Thanks to @jonrsharpe for the tip, using Function Overloads; also thanks to @Undo for his answer. Below is my typescript code implemented using Function Overloads:

function add(a: number, b: number): number
function add(a: string, b: string): string
function add(a: any, b: any): any {
    if (typeof a === 'number' && typeof b === 'number') {
        return a   b // a and b have full type hints, for example: `a.toFixed`
    }
    if (typeof a === 'string' && typeof b === 'string') {
        return a   b // a and b have full type hints, for example: `a.length` .
    }
    throw new Error('the types of a and b must be the same!')
}
console.log(add(1, 2)) //OK, 3
console.log(add('hello', 'world')) //OK, helloworld
add(1, 'world') // Error
  • Related