Skip to content

Commit bbd47cb

Browse files
JanTvrdikondrejmirtes
authored andcommitted
Make SensitiveParameterValue generic
`SensitiveParameterValue::getValue()` gives back exactly what was passed to the constructor, so the class can carry the value type instead of returning `mixed`. The template parameter has a `mixed` default, so existing code using a bare `SensitiveParameterValue` type keeps working and is not reported as missing type arguments on level 6 and above. Co-Authored-By: Claude Code Claude-Session: https://claude.ai/code/session_018u931gZ2H5LQNTzsSfNdF4
1 parent 61f10fd commit bbd47cb

3 files changed

Lines changed: 64 additions & 0 deletions

File tree

‎conf/config.neon‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ parameters:
154154
- ../stubs/iterable.stub
155155
- ../stubs/ArrayObject.stub
156156
- ../stubs/WeakReference.stub
157+
- ../stubs/SensitiveParameterValue.stub
157158
- ../stubs/ext-ds.stub
158159
- ../stubs/ImagickPixel.stub
159160
- ../stubs/PDOStatement.stub

‎stubs/SensitiveParameterValue.stub‎

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
/**
4+
* @template-covariant T = mixed
5+
*/
6+
final class SensitiveParameterValue
7+
{
8+
9+
/**
10+
* @param T $value
11+
*/
12+
public function __construct(mixed $value) {}
13+
14+
/**
15+
* @return T
16+
*/
17+
public function getValue(): mixed {}
18+
19+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php // lint >= 8.2
2+
3+
declare(strict_types = 1);
4+
5+
namespace SensitiveParameterValueGenerics;
6+
7+
use SensitiveParameterValue;
8+
use function PHPStan\Testing\assertType;
9+
10+
function inference(string $password, int $pin): void
11+
{
12+
$value = new SensitiveParameterValue($password);
13+
assertType('SensitiveParameterValue<string>', $value);
14+
assertType('string', $value->getValue());
15+
16+
$value = new SensitiveParameterValue([$pin]);
17+
assertType('SensitiveParameterValue<array{int}>', $value);
18+
assertType('array{int}', $value->getValue());
19+
}
20+
21+
/**
22+
* @param SensitiveParameterValue<non-empty-string> $value
23+
*/
24+
function withTypeArgs(SensitiveParameterValue $value): void
25+
{
26+
assertType('non-empty-string', $value->getValue());
27+
}
28+
29+
function withoutTypeArgs(SensitiveParameterValue $value): void
30+
{
31+
assertType('SensitiveParameterValue', $value);
32+
assertType('mixed', $value->getValue());
33+
}
34+
35+
/**
36+
* @param SensitiveParameterValue<non-empty-string> $value
37+
* @return SensitiveParameterValue<string>
38+
*/
39+
function covariance(SensitiveParameterValue $value): SensitiveParameterValue
40+
{
41+
assertType('SensitiveParameterValue<non-empty-string>', $value);
42+
43+
return $value;
44+
}

0 commit comments

Comments
 (0)