In plain untyped Javascript, it's not so hard to write a function which can operate on either numbers or bigints, depending on the arguments which are passed in:
const sumOfSquares = (a,b) => a*a + b*b;
sumOfSquares(3, 4); // returns 25
sumOfSquares(3n, 4n); // returns 25n
sumOfSquares(3n, 4); // throws a TypeError
It seems like there ought to be a way to declare this function in typescript so that the compiler will enforce that the arguments will work together. I tried
const sumOfSquares = <N extends bigint | number>(a: N, b: N): N =>
a * a + b * b;
But the compiler rejects this:
semantic error TS2322: Type 'number' is not assignable to type 'N'.
'number' is assignable to the constraint of type 'N', but 'N' could be instantiated with a different subtype of constraint 'number | bigint'.
Is there a different way to write the type declaration so that it will work?