Typed array like $arrIntOnly = [Int[]]@(1, 2, 3)
is useful to ensure that all elements are valid type, but is it possible to define multiple types like $arrIntOrString = [[Int | String][]]@(1, "two", 3)
?

- 382,024
- 64
- 607
- 775

- 499
- 1
- 3
- 17
1 Answers
PowerShell does not have a union data type, but you can use PowerShell's default arrays, which are [object[]]
-typed and can therefore contain elements of any type:
# Note: @(...) around the array isn't strictly necessary.
$arrIntOrString = 1, 'two', 3
There's no direct way to limit what specific types are permitted.
However, you can use a validation attribute - of type System.Management.Automation.ValidateScriptAttribute
in this case - to enforce that the elements are limited to specified types:
[ValidateScript({ $_ -is [int] -or $_ -is [string] })] $arrIntOrString = 1, 'two', 3
The above would enforce the specified types both on initial assignment and later modifications; e.g., the following attempt to later "add"[1] an element of a non-permitted type would fail:
# FAILS, because $true (of type [bool]) is neither an [int] nor [string]
$arrIntOrString += $true
Unfortunately, the error message is somewhat obscure: MetadataError: The variable cannot be validated because the value System.Object[] is not a valid value for the arrIntOrString variable.
Note that this validation is fairly slow, given that a script block ({ ... }
) must be executed for each element.
You can also apply this technique to parameter declarations, which in PowerShell (Core) 7+ allows you to define a custom error message:
Function Foo {
param(
# Note: Use of ErrorMessage requires PS 7+
[ValidateScript({ $_ -is [int] -or $_ -is [string] }, ErrorMessage = 'Please pass an integer or a string.')]
$IntOrString
)
$IntOrString
}
Foo -IntOrString 1.0 # Fails validation
[1] Arrays are fixed-length data structures, so what PowerShell does when you "add" to an array with +=
is to create a new array behind the scenes, with the new element(s) appended. Efficiently extensible alternatives to arrays are the non-generic System.Collections.ArrayList
type (e.g., [System.Collections.ArrayList] (1, 'two', 3)
) and the generic System.Collections.Generic.List`1
type (e.g., [System.Collections.Generic.List[object]] (1, 'two', 3)
). Then use the .Add()
method to add to these collections; note that the ArrayList.Add()
method returns a value, which you can suppress with $null = ...
. To initialize an empty collection of either type, cast @()
to the type literal or call its static ::new()
method.

- 382,024
- 64
- 607
- 775
-
2@theberzi, no, PowerShell doesn't have a union data type (I've updated the answer to make that clear), and this answer offers an _approximation_, in the context of _arrays_, which is what the question is about. However, you can apply the `ValidationScript` technique to parameter declarations as well - please see my update. – mklement0 Jun 15 '22 at 07:25