Here, I've got a function called returnWhatIPassIn, and it takes an input of unknown and returns an input of unknown so whatever I pass in here it's going to return unknown.


export function returnwWhatIPassIn(input: unknown): unknown {

return input

}


I'm not really fulfilling the promise of this function's name. I can fulfill it by using a function overload for each member of the thing that I want to do.

So I can do export function and have input be a string and suddenly I can pass in strings now. And that will return me a string.


export function returnwWhatIPassIn(input: string): string


I can also add another overload here which will be a number. So if I pass 12 to returnWhatIPassIn then it will return me a number.


export function returnwWhatIPassIn(input: number): number

...

const result = returnWhatIPassIn(12)


The issue here is that I'm going to have to add an overload for everything I can possibly imagine using this function for, which is a little bit tricky. If you have a set number of things that you want to pass in and return then that might be useful, but the real way to do this is with a generic.

So I can add TInput to returnWhatIPassIn. I replace all the unknowns with TInput and just return the input in the function body.


export function returnwWhatIPassIn<TInput>(input: TInput): TInput {

return input

}


Now, whatever I pass in is going to get returned to me. So I can pass in literally anything and it's all going to get returned to me. This is a good way of thinking about the difference between function overloads and generics.