When to Use Overloads and Unions
Solution 1: Function Overloads
The first solution is to use a function overload for the generator, and another for when it's an object.
Then inside of the implementation signature, we have the object or the function version:
function runGenerator(generator: () => string): string;
Transcript
0:00 Here's solution number one. This is using function overload, as we can see. We have a function overload for just this generator here and we also have one for when it's an object, so either a function or an object. Then inside the implementation signature, we have the object or the function version just here.
0:21 Now everything is fully typed. Everything seems to be working. We're going to get errors if we return something that isn't a string here. This seems pretty nice. You should be asking yourself, are function overloads required here? What am I getting out of declaring these as function overloads that I wouldn't get if I just declared it as a union?
0:46 Here, I've just taken off the top two signatures here, and everything still works. That's because the return type doesn't change based on the thing that you're passing in here. Let's say, for instance, that this was a different exercise completely. Let's say you run it with an object, it returns an object with result string here.
1:16 This is going to yell at us because it's not compatible with the implementation signature. This means that this is now going to return string or result string like this. That means that this needs to change here, result generator.run.
1:30 Now, when you pass it an object, it's going to return you an object. When you just pass it function, it's going to return you just a string. This wasn't the exercise. You should think carefully, because function overloads are at their best when you have a different return type based on something that you pass in.
1:52 If you just have the same return type, no matter what happens, it's always going to return a string, then you should probably be using a union to express these parameters instead.