-
-
Notifications
You must be signed in to change notification settings - Fork 97
Type System
Intelephense will make use of declared types, documented types and inferred types when providing language intelligence.
Declared types are provided through standard PHP syntax e.g. function toString(object $obj): string {}
. Documented types are provided through PHPDoc annotations. Where both a documented type and declared type is provided, Intelephense will prefer the documented type. This is because richer type information can be provided via documented types (e.g. generics, typed arrays). Providing declared or documented types improves the performance and the quality of language intelligence.
Inferred types are computed by intelephense and will be done so when a declared or documented type is not found or during control flow analysis. When a type is inferred it may be reduced to it's minimal representation. For example, MyClass|object
would become just object
because MyClass
is a subtype of object
.
Intelephense will type check declared types only and emit diagnostics if there is a type error. In a hierarchy of types, a subtype can be assigned to a supertype constraint. By default, Intelephense also permits the reverse. That is, a supertype or wider type can be assigned to a subtype or narrower type constraint. This behaviour was implemented due to the lack of syntax in PHP or PHPDoc to enable a developer to inline cast an expression or variable. If this behaviour is undesirable, it can be switched off by setting intelephense.diagnostics.relaxedTypeCheck
to false
, making the type checking more robust.
Many of the types below can only be used in PHPDoc as documented types. Please see the PHP type system documentation if you are unfamiliar with the standard PHP types.
Additional types used in other static analysis engines are not listed here as they are not fully supported. Intelephense attempts to fallback to an appropriate alternative in this situation.
mixed
is the supertype of all types. Any other type can be assigned to a type constraint of mixed
. If intelephense cannot determine a more specific type for a symbol then it is assigned mixed
. Because of this, Intelephense also allows mixed
to be assigned to any other type constraint as well, effectively turning off type checking for that particular symbol or expression. To switch off this behaviour you can set intelephense.diagnostics.relaxedTypeCheck
and intelephense.diagnostics.noMixedTypeCheck
to false
.
never
is the subtype of all types. This type can be assigned to any other type constraint. It is used to represent an impossibility in the code and can be used as the return type of a function that exits or always throws an exception.
Any of these types can be assigned to the other unless the strict_types
directive is used in the file -- declare(strict_types=1);
.
int
float
bool
string
void
null
true
false
-
unset
-- Intelephense borrows the PHPunset
keyword to use as a type that indicates an undefined variable.
-
'myString'
-- String literals are encapsulated in quotes. -
1
-- Integer literal.
object
-
\MyNs\MyClass
-- Classes, interfaces, enums can be fully qualified or not (MyClass
). If not fully qualified then the standard PHP name resolution rules apply to determine the fully qualified name. See note onintelephense.diagnostics.relaxedTypeCheck
at the top of this page. -
object{name: string, optional?: string}
-- Object shapes can be used to provide further information on dynamic object properties. This improves completion suggestions and type inference when accessing these properties. Optional properties can be declared by adding a?
at the end of the name. static
self
$this
array
-
array<TKey, TValue>
-- Generic form for an array where the type arguments represent the array key and value types respectively. If only a single type argument is provided then it will be normalised toarray<string|int, TValue>
. -
TValue[]
-- Represents a numeric indexed array where the element type isTValue
. -
array{name: string, 'height (cm)': float, optional?: string, ...<int, string>}
-- Array shapes can be used to provide further information on array element keys and types. This improves completion suggestions and type inference when accessing these elements. Keys with non alphanumeric characters need to be in quotes. Optional keys can be declared by adding a?
at the end of the key. Unspecified extra elements can be declared by adding an element of form...<TKey, TValue>
. Keys are optional and default to numerically indexed. For example a two element tuple would bearray{Type0, Type1}
. A mix of keyed and unkeyed elements is not supported.
-
callable
-- Base callable type that represents a callablestring
, callablearray
or a class that implements__invoke
. -
callable(TParamA $a, TParamB $b): TReturn
-- Callable type signatures can be defined to improve language intelligence. Parameter names are optional. The callable type should be wrapped in parentheses if it forms part of a union.Closure
can be used instead ofcallable
for a more specific type.
-
iterable
-- Alias forTraversable|array
. -
?A
-- Nullable type that is shorthand fornull|A
. Can not be used as part of a union or intersection type.
Type1|Type2|Type3
. A type which may have multiple atomic type representations. For example a type constraint of A|B
can be assigned type A
or B
. See note on intelephense.diagnostics.relaxedTypeCheck
at the top of this page.
Type1&Type2&Type3
. A composite type which consists of multiple atomic types. For example a type of A&B
can be assigned to type A
and to type B
. See note on intelephense.diagnostics.relaxedTypeCheck
at the top of this page. $this
should not be used in an intersection type due to ambiguities with by reference parameters.
When combining union and intersection types only a single level of nesting is permitted and the union must be the top level. For example, A|B|(C&D&E)
.
MyType<TypeArg1, TypeArg2>
. A generic type can be declared using one or many @template
PHPDoc annotations above the target class. Type arguments can then be supplied in the same order as the @template
declarations. The following built-in types are templated:
iterable<TKey, TValue>
Traversable<TKey, TValue>
array<TKey, TValue>
Iterator<TKey, TValue>
IteratorAggregate<TKey, TValue>
ArrayAccess<TKey, TValue>
WeakReference<TObject>
WeakMap<TKey, TValue>
Fiber<TStart, TResume, TReturn, TSuspend>
DatePeriod<TDate, TEnd>
ReflectionAttribute<TObject>
ReflectionClass<TObject>
Generator<TKey, TYield, TSend, TReturn>
ArrayObject<TKey, TValue>
SplDoublyLinkedList<TValue>
SplQueue<TValue>
SplStack<TValue>
SplHeap<TValue>
SplMinHeap<TValue>
SplMaxHeap<TValue>
SplPriorityQueue<TPriority, TValue>
SplFixedArray<TValue>
SplObjectStorage<TObject, TValue>
(TSubject is TCompare ? TTrue : TFalse)
. Sometimes the return type of a function may depend on the type of a parameter. A conditional type can be used without templates too by using the parameter name. For example, ($myParam is string ? string : null)
. Conditional types must be wrapped in parentheses. Conditional types may also be nested.
This type will resolve to a union of the keys of an array shape.
TArray[TKey]
. This type will resolve to the type of the value at index TKey
in TArray
. It is particularly useful in conjuction with key-of<TArray>
and shape types for mapping the return type when accessing container items with arbitrary strings. For example:
<?php
class MyContainerItem {}
class MyContainer
{
/**
* @template TMap of array{item: MyContainerItem, other: object}
* @template TKey of key-of<TMap>
* @param TKey $name
* @return TMap[TKey]
*/
function get($name): mixed {}
}
$container = new MyContainer();
$item = $container->get('item'); //$item is MyContainerItem
resource
-
class-string<T>
-- Astring
where the value is the name of classT
.
Support the development of this extension and access additional features by purchasing a licence at https://intelephense.com