# Adding assertions Psalm has five docblock annotations that allow you to specify that a function verifies facts about variables and properties: - `@psalm-assert` (used when throwing an exception) - `@psalm-assert-if-true`/`@psalm-assert-if-false` (used when returning a `bool`) - `@psalm-if-this-is`/`@psalm-this-out` (used when calling a method) A list of acceptable assertions [can be found here](assertion_syntax.md). ## Examples If you have a class that verified its input is an array of strings, you can make that clear to Psalm: ```php isValid(); } /** * @psalm-assert-if-false B $a */ function isInvalidB(A $a) : bool { return !$a instanceof B || !$a->isValid(); } function takesA(A $a) : void { if (isValidB($a)) { $a->bar(); } if (isInvalidB($a)) { // do something } else { $a->bar(); } $a->bar(); //error } ``` As well as getting Psalm to understand that the given data must be a certain type, you can also show that a variable must be not null: ```php exception * @psalm-assert-if-true Exception $this->getException() */ public function hasException(): bool { return $this->exception !== null; } public function getException(): ?Exception { return $this->exception; } public function foo(): void { if( $this->hasException() ) { // Psalm now knows that $this->exception is an instance of Exception echo $this->exception->getMessage(); } } } $result = new Result; if( $result->hasException() ) { // Psalm now knows that $result->getException() will return an instance of Exception echo $result->getException()->getMessage(); } ``` Please note that the example above only works if you enable [method call memoization](https://psalm.dev/docs/running_psalm/configuration/#memoizemethodcallresults) in the config file or annotate the class as [immutable](https://psalm.dev/docs/annotating_code/supported_annotations/#psalm-immutable). You can use `@psalm-this-out` to change the template arguments of a method after a method call, to reflect changes to the object's internal state. You can also make assertions on the object's template arguments using `@psalm-if-this-is`. ```php */ private array $data; /** * @param T $data */ public function __construct($data) { $this->data = [$data]; } /** * @template NewT * * @param NewT $data * * @psalm-this-out self * * @return void */ public function addData($data) { /** @var self $this */ $this->data []= $data; } /** * @template NewT * * @param NewT $data * * @psalm-this-out self * * @return void */ public function setData($data) { /** @var self $this */ $this->data = [$data]; } /** * @psalm-if-this-is a */ public function test(): void { } } $i = new a(123); // OK - $i is a<123> $i->test(); $i->addData(321); // OK - $i is a<123|321> $i->test(); $i->setData("test"); // IfThisIsMismatch - Class is not a as required by psalm-if-this-is $i->test(); ```