What are these called? When scripting in powershell I can use them to set or convert the data type of my variable, but what is the term for this? Is there an official doc for these?
Example:
$var = @("hello","world")
If ($var -is [array]) { write-host "$var is an array" }
Don Cruickshank's helpful answer provides one piece of the puzzle, but let me try give a comprehensive overview:
By itself, a [<fullTypeNameOrTypeAccelerator>]
expression is a type literal, i.e. a reference to a .NET type in the form of a System.Reflection.TypeInfo
instance, which is rich source of reflection on the type it represents.
<fullTypeNameOrTypeAccelerator>
can be the full name of a .NET type (e.g., [System.Text.RegularExpressions.Regex]
- optionally with the System.
prefix omitted ([Text.RegularExpressions.Regex]
) or the name of a PowerShell type accelerator (e.g, [regex]
)
Type literals by themselves are used:
Typically, to access static members (typically methods) via ::
, the static member-access operator; e.g.:
# Call the static 'Match' method of the [regex]
# (System.Text.RegularExpressions.Regex) type.
# -> '10'
[regex]::Match('A10', '\d+').Value
Less frequently, to reflect on the given type by calling the instance methods of the TypeInfo
instance that every type literal is; e.g.:
# Get the names of all .NET interfaces that the [regex]
# (System.Text.RegularExpressions.Regex) implements.
# -> 'ISerializable'
[regex].GetInterfaces().Name
Type literals are also used in the following constructs:
As casts, to convert (coerce) the (RHS[1]) operand to the specified type or to construct an instance, if possible:
# Convert a string to [datetime] (System.DateTime).
# Equivalent to the following call:
# [datetime]::Parse('1970-01-01', [cultureinfo]::InvariantCulture)
[datetime] '1970-01-01'
# Construct a [regex] instance.
# The same as the following constructor call:
# [regex]::new('\d+')
$re = [regex] '\d+'
As type constraints:
To specify the type of a parameter variable in a function or script:
function foo { param([datetime] $d) $d.Year }; foo '1970-01-01'
To lock in the type of a regular variable for all future assignments:[2]
[datetime] $foo = '1970-01-01'
# ...
$foo = '2021-01-01' # the string is now implicitly forced to [datetime]
As the RHS of the -is
and -as
operators, for type tests and conditional conversions:
-is
tests not only for the exact type, but also for derived types as well as interface implementations:
# Exact type match (the `Get-Date` cmdlet outputs instances of [datetime])
(Get-Date) -is [datetime] # $true
# Match via a *derived* type:
# `Get-Item /` outputs an instance of type [System.IO.DirectoryInfo],
# which derives from [System.IO.FileSystemInfo]
(Get-Item /) -is [System.IO.FileSystemInfo] # $true
# Match via an *interface* implementation:
# Arrays implement the [System.Collections.IEnumerable] interface.
1..3 -is [System.Collections.IEnumerable] # true
-as
converts the LHS instance to an instance of the RHS type if possible, and returns $null
otherwise:
'42' -as [int] # 42
'foo' -as [int] # $null
[PowerShell v7.3+ only] As the type arguments in generic method calls:
E.g, the following calls the Enumerable.OfType<TResult>(IEnumerable)
LINQ method with [int]
as its type argument (thereby requesting that only enumerable elements that are of that type be returned):
# -> 2, 4
[System.Linq.Enumerable]::OfType[int](@('one', 2, 'three', 4))
[1] In the context of operators and mathematical equations, the initialisms LHS and RHS are commonly used, referring to the left-hand side and right-hand side operands, respectively.
[2] Technically, there is no real difference between a parameter and a regular variable: the type constraints functions the same way in both cases, but parameter variables, after having been bound (assigned to) automatically on invocation, aren't usually assigned to again.