Skip to content

Commit 8943feb

Browse files
Add test
1 parent eae15bb commit 8943feb

1 file changed

Lines changed: 90 additions & 0 deletions

File tree

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?php // lint >= 8.1
2+
3+
declare(strict_types = 1);
4+
5+
namespace Bug14203;
6+
7+
use function PHPStan\Testing\assertType;
8+
9+
/**
10+
* @template TKey of array-key
11+
* @template TValue
12+
*/
13+
class Collection
14+
{
15+
/**
16+
* Create a new collection.
17+
*
18+
* @param array<TKey, TValue> $items
19+
*/
20+
final public function __construct(protected $items = [])
21+
{
22+
}
23+
24+
/**
25+
* @template TMapValue
26+
*
27+
* @param callable(TValue, TKey): TMapValue $callback
28+
* @return static<TKey, TMapValue>
29+
*/
30+
public function map(callable $callback)
31+
{
32+
$newItems = [];
33+
34+
foreach ($this->items as $key => $value) {
35+
$newItems[$key] = $callback($value, $key);
36+
}
37+
38+
return new static($newItems);
39+
}
40+
}
41+
42+
class SpecificA {
43+
public function __construct(
44+
public readonly int $valueA,
45+
public readonly string $someSharedValue,
46+
) {}
47+
}
48+
49+
class SpecificB {
50+
public function __construct(
51+
public readonly int $valueB,
52+
public readonly string $someSharedValue,
53+
) {}
54+
}
55+
56+
class MyDTO {
57+
public function __construct(
58+
public readonly string $thatSharedValue,
59+
) {}
60+
}
61+
62+
function works(): void {
63+
$myCollection = new Collection([new SpecificA(1, 'A'), new SpecificB(2, 'B')]);
64+
65+
$result = $myCollection->map(static fn (SpecificA|SpecificB $specific): MyDTO => new MyDTO($specific->someSharedValue));
66+
assertType('Bug14203\Collection<int, Bug14203\MyDTO>', $result);
67+
}
68+
69+
/**
70+
* @return Collection<int, SpecificA>
71+
*/
72+
function getA(): Collection {
73+
return new Collection([new SpecificA(1, 'A')]);
74+
}
75+
76+
/**
77+
* @return Collection<int, SpecificB>
78+
*/
79+
function getB(): Collection {
80+
return new Collection([new SpecificB(2, 'B')]);
81+
}
82+
83+
function breaks(): void {
84+
$myCollection = random_int(0, 1) === 0
85+
? getA()
86+
: getB();
87+
88+
$result = $myCollection->map(static fn (SpecificA|SpecificB $specific): MyDTO => new MyDTO($specific->someSharedValue));
89+
assertType('Bug14203\Collection<int, Bug14203\MyDTO>', $result);
90+
}

0 commit comments

Comments
 (0)