/
generic-unions.php
95 lines (80 loc) · 1.56 KB
/
generic-unions.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
<?php
namespace GenericUnions;
use function PHPStan\Testing\assertType;
class Foo
{
/**
* @template T
* @param T|null $p
* @return T
*/
public function doFoo($p)
{
if ($p === null) {
throw new \Exception();
}
return $p;
}
/**
* @template T
* @param T $p
* @return T
*/
public function doBar($p)
{
return $p;
}
/**
* @template T
* @param T|int|float $p
* @return T
*/
public function doBaz($p)
{
return $p;
}
/**
* @param int|string $stringOrInt
*/
public function foo(
?string $nullableString,
$stringOrInt
): void
{
assertType('string', $this->doFoo($nullableString));
assertType('int|string', $this->doFoo($stringOrInt));
assertType('string|null', $this->doBar($nullableString));
assertType('int', $this->doBaz(1));
assertType('string', $this->doBaz('foo'));
assertType('float', $this->doBaz(1.2));
assertType('string', $this->doBaz($stringOrInt));
}
}
/**
*
* @template TGetDefault
* @template TKey
*
* @param TKey $key
* @param TGetDefault|(\Closure(): TGetDefault) $default
* @return TKey|TGetDefault
*/
function getWithDefault($key, $default = null)
{
if(rand(0,10) > 5) {
return $key;
}
if (is_callable($default)) {
return $default();
}
return $default;
}
assertType('int|null', getWithDefault(3));
assertType('int|string', getWithDefault(3, 'foo'));
assertType('int|string', getWithDefault(3, function () {
return 'foo';
}));
assertType('GenericUnions\Foo|int', getWithDefault(3, function () {
return new Foo;
}));
assertType('GenericUnions\Foo|int', getWithDefault(3, new Foo));