The Microsoft TypeScript training shows the way to solve the problem.
Please check the section "Use the methods and properties of a generic type" in the module "Define generics in TypeScript"
type ValidTypes = string | number;
function add<T extends ValidTypes> (a:T, b:T) // Return type is inferred
{
if (typeof a === 'number' && typeof b === 'number') {
return a + b;
} else if (typeof a === 'string' && typeof b === 'string') {
return a + b;
} else {
return undefined;
}
}
console.log(add<number>(5, 6)); // 11
console.log(add<string>("5", "6")); // "56"
console.log(add (5, "6")); // undefined
TS Playground
And if you want to mix the parameter types
type ValidTypes = string | number;
function add<T extends ValidTypes, U extends ValidTypes> (a:T, b:U) // Return type is inferred
{
if (typeof a === 'number' && typeof b === 'number') {
return a + b;
} else if (typeof a === 'string' && typeof b === 'string') {
return a + b;
} else if (typeof a === 'number' && typeof b === 'string') {
return a + b;
} else if (typeof a === 'string' && typeof b === 'number') {
return a + b;
} else {
return undefined;
}
}
console.log(add<number, number>(5, 6)); // 11
console.log(add<string,string>("5", "6")); // "56"
console.log(add<string,number>("5", 6)); // "56"
console.log(add<number,string>(5, "6")); // "56"
console.log(add<number,number>(5, "6")); // Error 2345: Argument of type 'string' is not assignable to parameter of type 'number'
console.log(add (5, 6)); // 11
console.log(add("5", "6")); // "56"
console.log(add (5, "6")); // "56"
console.log(add ("5", 6)); // "56"
console.log(add (5, null)); // undefined
TS Playground
["a", "b", "c"].reduce(add)
where you take two strings at a time and pass them through a binary function. – Fotheringhay