Parameterised Types 🧩

Published Sep 23 2023

php
types
creational

Parameterised types, also known as generics, allow you to define the specific type of data that a variable or class can handle. This is valuable for error prevention and enhancing the robustness of your code. However, it's important to note that not all programming languages offer support for this feature. Statically typed languages such as Java or C# have built-in support for generics.

Now, what about PHP? Prior to the official support of type declarations since PHP 7 through to 8, achieving parameterised types required the use of libraries like PHPStan and Psalm. With the help of these libraries, this is how we would write our code:

// With PHPStan

class Box {
    /**
     * @var mixed
     */
    private $value;

    /**
     * @param mixed $value
     */
    public function __construct($value) {
        $this->value = $value;
    }

    /**
     * @return string
     */
    public function getValue() {
        return $this->value;
    }
}

$intBox = new Box(42);
echo $intBox->getValue() . PHP_EOL; // This will be caught by PHPStan (I think 😅)

In the above example, we use annotations to set the type rules for the return type of getValue(). When we set a different type than the expected return type, our getValue() method will throw an error, courtesy of PHPStan.

Since PHP 7.0.x, we have had access to the following directive:

declare(strict_types=1);

This directive enables strict typing for scalar types (int, float, string, bool). When strict typing is enabled, PHP will throw a TypeError exception if a scalar value is passed to a function or assigned to a variable that is expecting a different type.

Here's an example:

declare(strict_types=1);

function add(int $a, int $b): int {
    return $a + $b;
}

$sum = add(1, '2'); // This will throw a TypeError exception

This means that we can now do parameterised types like this:

// Without non-native libraries

class Box {
   private int $value;

   public function __construct(int $value) {
       $this->value = $value;
   }

   public function getValue(): int {
       return $this->value;
   }
}

$intBox = new Box("42");
echo $intBox->getValue(); // This will be caught by PHP 7.0.x

Since PHP 7.0.x, strict typing in PHP has since gotten better. More features have been added and I believe that this is just the beginning 😁

Parameterised Types as a creational pattern

In addition to object composition and class inheritance, parameterised types gives us a third way to compose in object-oriented programming.

Consider the following example:

class OlympicTeam {
    public function addAthlete($athlete) {
        $this->repository->add($athlete);
    }
}

class SwimmingTeam extends OlympicTeam {
    public function addAthlete(Swimmer $athlete) {
        parent::addAthlete($athlete);
    }
}

$team = new SwimmingTeam();
$team->addAthlete(new Sprinter());

In the above example, the SwimmingTeam class inherits from OlympicTeam. In this example, let's say that it is overwriting the addAthlete() method, dictating that the parameter passed be an object type of Swimmer. This means that any other parameter passed to addAthlete() that isn't a type of Swimmer will cause the method to throw an exception.

This is good because we get to add type safety to the parent class without rewriting the original method. Another benefit is that we get to extend the parent class with additional functionality for specific athlete types, making our code more robust.

Ok bye!

© 2025 Elvis Magagula, All rights reserved