Big Smile
Big Smile

Reputation: 1124

Why are function parameters not treated as compulsory when implementing an interface?

I have recently noticed that I was able to implement a function from an interface and remove the parameters and that worked fine. I have some sample code below to demonstrate. Shouldn't the class implementing the interface be forced to also implement the correct number and type of parameters?

TypeScript version: 4.1.3

The sample interface:

interface IVehicle {
  turn(direction: string, degree: number): void;
  turnHeadlights(toggle: boolean): void;
} 

Example one:

class Vehicle implements IVehicle {
  turn(direction: string): void {
    throw new Error("Method not implemented.");
  }

  turnHeadlights(toggle: boolean): void {
    throw new Error("Method not implemented.");
  }
}

Example two:

class VehicleStub implements IVehicle {
  turn(): void {
    throw new Error("Method not implemented.");
  }

  turnHeadlights(): void {
    throw new Error("Method not implemented.");
  }
}

Upvotes: 2

Views: 852

Answers (2)

Nicholas Tower
Nicholas Tower

Reputation: 84982

Typescript is deliberately designed this way. The types on functions are there to make sure that all the right data gets passed into the function. It does not force the function to actually do something with the values.

It's actually quite common for javascript code to leave out arguments that aren't used. For example, the array functions such as map:

const array1 = [1, 2, 3];
const array2 = array1.map(value => value * 2); // creates [2, 4, 6]

But the function you pass in actually receives 3 parameters, not 1. If typescript forced you to list them all, you would have to rewrite this as:

const array1 = [1, 2, 3];
const array2 = array1.map((value, index, arr) => value * 2);

There's little to be gained by forcing you to declare the variables you won't use, so they designed typescript to not force that. As long as your function is compatible with the data that's being passed in, it will allow it.

For more information, see this page: https://www.typescriptlang.org/docs/handbook/type-compatibility.html#comparing-two-functions

Upvotes: 5

axiac
axiac

Reputation: 72226

The classes that implement an interface are allowed to omit the rightmost arguments of the methods.

In your example, Vehicle.turn() uses only the first argument (direction) and omits the rest, starting with the second argument (degree). Only the rightmost arguments can be omitted, it is not possible to omit an argument and specify one that is on its right.

This is useful when the implementation does not use those arguments and simplifies the code.

This shapes the behaviour when the method is called. The declared type of the object used to call the method tells what signature of the method to use (the one declared in the interface or the one declared in the class that implements it).

For example:

const vehicle1: IVehicle = new Vehicle();
// This does not compile, it requires two arguments for IVehicle.turn()
vehicle1.turn('left');

const vehicle3: Vehicle = new Vehicle();
// This compiles, Vehicle.turn() requires only one argument
vehicle3.turn('left');

Check it on the TypeScript playground.

Upvotes: 1

Related Questions