Skip to content

Commit e9dd67c

Browse files
committed
feat: promoted property support
1 parent a1cfc1c commit e9dd67c

File tree

3 files changed

+150
-0
lines changed

3 files changed

+150
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
namespace Spatie\TypeScriptTransformer\TypeReflectors;
4+
5+
use ReflectionProperty;
6+
use ReflectionType;
7+
8+
class PromotedPropertyTypeReflector extends TypeReflector
9+
{
10+
public static function create(ReflectionProperty $reflection): self
11+
{
12+
return new self($reflection);
13+
}
14+
15+
public function __construct(ReflectionProperty $reflection)
16+
{
17+
parent::__construct($reflection);
18+
}
19+
20+
protected function getDocblock(): string
21+
{
22+
return $this->reflection->getDeclaringClass()->getMethod('__construct')->getDocComment();
23+
}
24+
25+
protected function docblockRegex(): string
26+
{
27+
$parameterName = $this->reflection->getName();
28+
return '/@param\s+([^\s<]+(?:<[^>]*>)?)\s+\$' . preg_quote($parameterName, '/') . '\b/m';
29+
30+
}
31+
32+
protected function getReflectionType(): ?ReflectionType
33+
{
34+
return $this->reflection->getType();
35+
}
36+
37+
protected function getAttributes(): array
38+
{
39+
return $this->reflection->getAttributes();
40+
}
41+
}

src/TypeReflectors/TypeReflector.php

+3
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ public function __construct(protected ReflectionMethod|ReflectionProperty|Reflec
3636
public static function new(ReflectionMethod|ReflectionProperty|ReflectionParameter $reflection): static
3737
{
3838
if ($reflection instanceof ReflectionProperty) {
39+
if ($reflection->isPromoted()) {
40+
return new PromotedPropertyTypeReflector($reflection);
41+
}
3942
return new PropertyTypeReflector($reflection);
4043
}
4144

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
<?php
2+
3+
use Spatie\TypeScriptTransformer\TypeReflectors\PromotedPropertyTypeReflector;
4+
use function PHPUnit\Framework\assertEquals;
5+
use Spatie\TypeScriptTransformer\Attributes\LiteralTypeScriptType;
6+
7+
it('can reflect from reflection', function () {
8+
$class = new class(0, 0, 0, 0, 0) {
9+
public function __construct(
10+
public int $p1,
11+
public ?int $p2,
12+
public int | float $p3,
13+
public int | float | null $p4,
14+
public $p5,
15+
) {}
16+
};
17+
18+
assertEquals(
19+
'int',
20+
(string) PromotedPropertyTypeReflector::create(new ReflectionProperty($class, 'p1'))->reflect(),
21+
);
22+
23+
assertEquals(
24+
'?int',
25+
(string) PromotedPropertyTypeReflector::create(new ReflectionProperty($class, 'p2'))->reflect(),
26+
);
27+
28+
assertEquals(
29+
'int|float',
30+
(string) PromotedPropertyTypeReflector::create(new ReflectionProperty($class, 'p3'))->reflect(),
31+
);
32+
33+
assertEquals(
34+
'int|float|null',
35+
(string) PromotedPropertyTypeReflector::create(new ReflectionProperty($class, 'p4'))->reflect(),
36+
);
37+
38+
assertEquals(
39+
'any',
40+
(string) PromotedPropertyTypeReflector::create(new ReflectionProperty($class, 'p5'))->reflect(),
41+
);
42+
});
43+
44+
it('can reflect from docblock', function () {
45+
$class = new class(0, 0, 0, 0, 0, []) {
46+
/**
47+
* @param int $p1
48+
* @param ?int $p2
49+
* @param int|float $p3
50+
* @param int|float|null $p4
51+
* @param array<array-key, string> $p6
52+
*/
53+
public function __construct(
54+
public int $p1,
55+
public ?int $p2,
56+
public int | float $p3,
57+
public int | float | null $p4,
58+
public $p5,
59+
public array $p6,
60+
) {}
61+
};
62+
63+
assertEquals(
64+
'int',
65+
(string) PromotedPropertyTypeReflector::create(new ReflectionProperty($class, 'p1'))->reflect(),
66+
);
67+
68+
assertEquals(
69+
'?int',
70+
(string) PromotedPropertyTypeReflector::create(new ReflectionProperty($class, 'p2'))->reflect(),
71+
);
72+
73+
assertEquals(
74+
'int|float',
75+
(string) PromotedPropertyTypeReflector::create(new ReflectionProperty($class, 'p3'))->reflect(),
76+
);
77+
78+
assertEquals(
79+
'int|float|null',
80+
(string) PromotedPropertyTypeReflector::create(new ReflectionProperty($class, 'p4'))->reflect(),
81+
);
82+
83+
assertEquals(
84+
'any',
85+
(string) PromotedPropertyTypeReflector::create(new ReflectionProperty($class, 'p5'))->reflect(),
86+
);
87+
88+
assertEquals(
89+
'array<array-key,string>',
90+
(string) PromotedPropertyTypeReflector::create(new ReflectionProperty($class, 'p6'))->reflect(),
91+
);
92+
});
93+
94+
it('can reflect from attribute', function () {
95+
$class = new class(0){
96+
public function __construct(
97+
#[LiteralTypeScriptType('Integer')]
98+
public $p1,
99+
) {}
100+
};
101+
102+
assertEquals(
103+
'Integer',
104+
(string) PromotedPropertyTypeReflector::create(new ReflectionProperty($class, 'p1'))->reflect(),
105+
);
106+
});

0 commit comments

Comments
 (0)