PowerShell does this because the following two commands behave differently:
Some-Command -Param
Some-Command "-Param"
In the first case, Some-Command is called with a parameter named Param, in the second case Some-Command is called with a positional argument that has the value "-Param".
With a little digging, we can figure out how PowerShell knows the difference.
function foo { $args[0] }
foo -SomeParam | Get-Member -MemberType NoteProperty -Force
After running the above, we see the following output:
TypeName: System.String
Name MemberType Definition
---- ---------- ----------
<CommandParameterName> NoteProperty System.String <CommandParameterName>=SomeParam
We see that PowerShell added a NoteProperty to the value in $args. We can conclude from this that PowerShell is using that NoteProperty when splatting to decide if the value in the array is passed as a value or as a parameter.
So - one solution that I don't recommend - you could add a NoteProperty to your strings that are really parameters. I don't recommend this because it would rely on an undocumented implementation detail.
An alternative solution is to use a function like my foo function to turn a syntactic switch into a value that splats as a parameter. That might look like:
function Get-AsParameter { $args[0] }
$b = "xxx", (Get-AsParameter -T)
TestArgs @b