While implementing a generic function on sets in Typescript, I noticed that the compiler is unable to infer the base type of two arguments.
function union<T>(first: Set<T>, second: Set<T>): Set<T> {
const newSet = new Set<T>(first);
for (const element of second)
newSet.add(element);
return newSet;
}
class Animal { }
class Dog extends Animal {
bark() { console.info('Woof!'); }
}
class Cat extends Animal {
meow() { console.info('Meow!'); }
}
const a = new Set<Dog>();
const b = new Set<Cat>();
Then if I call union, Typescript is unable to infer that T should be Animal.
const c = union(a, b);
// This results in the error:
// Argument of type 'Set<Cat>' is not assignable to parameter of type 'Set<Dog>'.
// Property 'bark' is missing in type 'Cat' but required in type 'Dog'.ts(2345)
But if I explicitly call union with T = Animal, it works fine:
const d = union<Animal>(a, b);
What am I doing wrong?