Typecript: Overloading functions with tuples

Typecript: Overloading functions with tuples

Overloading a function on a programming language means using the same function but with different types of arguments or increasing the number of arguments.

What are tuples?

Is a mechanism in typescript to strictly define an Array, define size, define the types of each entry in the Array, each entry may support different types...

What is function overloading?

Is the capacity in a programming language to make any function support different signatures, using the same function name but with different sizes of arguments and different types e.g:

function addVehicle(type: CarType, vehiculeInfo: { doors: number }) { ... }
function addVehicle(type: TruckType, vehiculeInfo: { axles: number }) { ... }
function addVehicle(type: BikeType, vehiculeInfo: { hasSidecar: boolean }) { ... }

in typescript this code will fail, we can't re-define the function multiple times:

Duplicate function implementation.ts(2393)

So... let's continue

As you know any function in javascript supports the keyword arguments, which is an Array and contains the values passed to the functions per api docs e.g:

function add(number1: number, number2: number) {
  console.log(number1, number2)
}

is the same as doing:

function add(number1: number, number2: number) {
  console.log(arguments[0], arguments[1])
}

Fix this problem with tuples in typescript

We are going to define the vehicles types:

type CarType = "car";
type TruckType = "truck";
type BikeType = "bike";
type VehicleType = CarType | TruckType | BikeType;

Now let's create the tuples:

type AddVehicleArguments =
  | [CarType, { doors: number }]
  | [TruckType, { axles: number }]
  | [BikeType, { hasSidecar: boolean }];

Define the function that will support different arguments types:

function addVehicle(...args: AddVehicleArguments) {
  const vehiculeType: VehicleType = args[0];
  console.log(vehiculeType, args[1]);
}

...And voilá, function overloaded with type checking:

addVehicle("car", { doors: 2 });
addVehicle("car", { axles: 2 });

addVehicle("truck", { axles: 3 });
addVehicle("bike", { hasSidecar: false });

If the function is called with an argument that is not matching a tuple, typescript will complain, which is what we expect: image.png

Argument of type '["car", { axles: number; }]' is not assignable to parameter of type 'AddVehicleArguments'.
  Type '["car", { axles: number; }]' is not assignable to type '["car", { doors: number; }]'.
    Type at position 1 in source is not compatible with type at position 1 in target.
      Type '{ axles: number; }' is not assignable to type '{ doors: number; }'.
        Object literal may only specify known properties,

Conclusion

This approach is really helpful to create functions that need to be overloaded, using different types, any number (in this case is only 2 argument functions, but can be even more).

Any feedback or question, please post down below...

Source code

codesandbox.io/s/function-overloading-with-..