1
0
mirror of https://github.com/danog/psalm.git synced 2024-11-30 04:39:00 +01:00
This commit is contained in:
Daniil Gentili 2022-12-30 21:51:27 +01:00
parent 9b4857a606
commit 0f7eed0dca
3 changed files with 10 additions and 2 deletions

View File

@ -3,12 +3,14 @@
In PHP, the `array` type is commonly used to represent three different data structures: In PHP, the `array` type is commonly used to represent three different data structures:
[List](https://en.wikipedia.org/wiki/List_(abstract_data_type)): [List](https://en.wikipedia.org/wiki/List_(abstract_data_type)):
```php ```php
<?php <?php
$a = [1, 2, 3, 4, 5]; $a = [1, 2, 3, 4, 5];
``` ```
[Associative array](https://en.wikipedia.org/wiki/Associative_array): [Associative array](https://en.wikipedia.org/wiki/Associative_array):
```php ```php
<?php <?php
$a = [0 => 'hello', 5 => 'goodbye']; $a = [0 => 'hello', 5 => 'goodbye'];
@ -16,6 +18,7 @@ $b = ['a' => 'AA', 'b' => 'BB', 'c' => 'CC']
``` ```
Makeshift [Structs](https://en.wikipedia.org/wiki/Struct_(C_programming_language)): Makeshift [Structs](https://en.wikipedia.org/wiki/Struct_(C_programming_language)):
```php ```php
<?php <?php
$a = ['name' => 'Psalm', 'type' => 'tool']; $a = ['name' => 'Psalm', 'type' => 'tool'];
@ -28,6 +31,7 @@ Psalm has a few different ways to represent arrays in its type system:
## Generic arrays ## Generic arrays
Psalm uses a syntax [borrowed from Java](https://en.wikipedia.org/wiki/Generics_in_Java) that allows you to denote the types of both keys *and* values: Psalm uses a syntax [borrowed from Java](https://en.wikipedia.org/wiki/Generics_in_Java) that allows you to denote the types of both keys *and* values:
```php ```php
/** @return array<TKey, TValue> */ /** @return array<TKey, TValue> */
``` ```
@ -37,6 +41,7 @@ You can also specify that an array is non-empty with the special type `non-empty
### PHPDoc syntax ### PHPDoc syntax
PHPDoc [allows you to specify](https://docs.phpdoc.org/latest/guide/references/phpdoc/types.html#arrays) the type of values a generic array holds with the annotation: PHPDoc [allows you to specify](https://docs.phpdoc.org/latest/guide/references/phpdoc/types.html#arrays) the type of values a generic array holds with the annotation:
```php ```php
/** @return ValueType[] */ /** @return ValueType[] */
``` ```
@ -179,14 +184,12 @@ Optional keys can be denoted by a specifying keys for all elements and specifyin
List shapes are essentially n-tuples [from a type theory perspective](https://en.wikipedia.org/wiki/Tuple#Type_theory). List shapes are essentially n-tuples [from a type theory perspective](https://en.wikipedia.org/wiki/Tuple#Type_theory).
## Unsealed array and list shapes ## Unsealed array and list shapes
Starting from Psalm v5, array shapes and list shapes can be marked as open by adding `...` as their last element. Starting from Psalm v5, array shapes and list shapes can be marked as open by adding `...` as their last element.
Here we have a function `handleOptions` that takes an array of options. The type tells us it has a single known key with type `string`, and potentially many other keys of unknown types. Here we have a function `handleOptions` that takes an array of options. The type tells us it has a single known key with type `string`, and potentially many other keys of unknown types.
```php ```php
/** @param array{verbose: string, ...} $options */ /** @param array{verbose: string, ...} $options */
function handleOptions(array $options): float { function handleOptions(array $options): float {

View File

@ -3,16 +3,19 @@
An annotation of the form `Type1&Type2&Type3` is an _Intersection Type_. Any value must satisfy `Type1`, `Type2` and `Type3` simultaneously. `Type1`, `Type2` and `Type3` are all [atomic types](atomic_types.md). An annotation of the form `Type1&Type2&Type3` is an _Intersection Type_. Any value must satisfy `Type1`, `Type2` and `Type3` simultaneously. `Type1`, `Type2` and `Type3` are all [atomic types](atomic_types.md).
For example, after this statement in a PHPUnit test: For example, after this statement in a PHPUnit test:
```php ```php
<?php <?php
$hare = $this->createMock(Hare::class); $hare = $this->createMock(Hare::class);
``` ```
`$hare` will be an instance of a class that extends `Hare`, and implements `\PHPUnit\Framework\MockObject\MockObject`. So `$hare` will be an instance of a class that extends `Hare`, and implements `\PHPUnit\Framework\MockObject\MockObject`. So
`$hare` is typed as `Hare&\PHPUnit\Framework\MockObject\MockObject`. You can use this syntax whenever a value is `$hare` is typed as `Hare&\PHPUnit\Framework\MockObject\MockObject`. You can use this syntax whenever a value is
required to implement multiple interfaces. required to implement multiple interfaces.
Another use case is being able to merge object-like arrays: Another use case is being able to merge object-like arrays:
```php ```php
/** /**
* @psalm-type A=array{a: int} * @psalm-type A=array{a: int}
@ -27,6 +30,7 @@ function foo($a, $b) {
return $a + $b; return $a + $b;
} }
``` ```
The returned type will contain the properties of both `A` and `B`. In other words, it will be `{a: int, b: int}`. The returned type will contain the properties of both `A` and `B`. In other words, it will be `{a: int, b: int}`.
Intersections are only valid for lists of only *object types* and lists of only *object-like arrays*. Intersections are only valid for lists of only *object types* and lists of only *object-like arrays*.

View File

@ -10,6 +10,7 @@ This is the _top type_ in PHP's type system, and represents a lack of type infor
It can be aliased to `no-return` or `never-return` in docblocks. Note: it replaced the old `empty` type that used to exist in Psalm It can be aliased to `no-return` or `never-return` in docblocks. Note: it replaced the old `empty` type that used to exist in Psalm
This is the _bottom type_ in PHP's type system. It's used to describe a type that has no possible value. It can happen in multiple cases: This is the _bottom type_ in PHP's type system. It's used to describe a type that has no possible value. It can happen in multiple cases:
- the actual `never` type from PHP 8.1 (can be used in docblocks for older versions). This type can be used as a return type for functions that will never return, either because they always throw exceptions or always exit() - the actual `never` type from PHP 8.1 (can be used in docblocks for older versions). This type can be used as a return type for functions that will never return, either because they always throw exceptions or always exit()
- an union type that have been stripped for all its possible types. (For example, if a variable is `string|int` and we perform a is_bool() check in a condition, the type of the variable in the condition will be `never` as the condition will never be entered) - an union type that have been stripped for all its possible types. (For example, if a variable is `string|int` and we perform a is_bool() check in a condition, the type of the variable in the condition will be `never` as the condition will never be entered)
- it can represent a placeholder for types yet to come — a good example is the type of the empty array `[]`, which Psalm types as `array<never, never>`, the content of the array is void so it can accept any content - it can represent a placeholder for types yet to come — a good example is the type of the empty array `[]`, which Psalm types as `array<never, never>`, the content of the array is void so it can accept any content