1: <?php declare(strict_types = 1);
2:
3: namespace PHPStan\Type;
4:
5: use PHPStan\Type\Generic\TemplateTypeVariance;
6: use PHPStan\Type\Traits\LateResolvableTypeTrait;
7: use PHPStan\Type\Traits\NonGeneralizableTypeTrait;
8: use function sprintf;
9:
10: /** @api */
11: class KeyOfType implements CompoundType, LateResolvableType
12: {
13:
14: use LateResolvableTypeTrait;
15: use NonGeneralizableTypeTrait;
16:
17: public function __construct(private Type $type)
18: {
19: }
20:
21: public function getType(): Type
22: {
23: return $this->type;
24: }
25:
26: public function getReferencedClasses(): array
27: {
28: return $this->type->getReferencedClasses();
29: }
30:
31: public function getReferencedTemplateTypes(TemplateTypeVariance $positionVariance): array
32: {
33: return $this->type->getReferencedTemplateTypes($positionVariance);
34: }
35:
36: public function equals(Type $type): bool
37: {
38: return $type instanceof self
39: && $this->type->equals($type->type);
40: }
41:
42: public function describe(VerbosityLevel $level): string
43: {
44: return sprintf('key-of<%s>', $this->type->describe($level));
45: }
46:
47: public function isResolvable(): bool
48: {
49: return !TypeUtils::containsTemplateType($this->type);
50: }
51:
52: protected function getResult(): Type
53: {
54: return $this->type->getIterableKeyType();
55: }
56:
57: /**
58: * @param callable(Type): Type $cb
59: */
60: public function traverse(callable $cb): Type
61: {
62: $type = $cb($this->type);
63:
64: if ($this->type === $type) {
65: return $this;
66: }
67:
68: return new KeyOfType($type);
69: }
70:
71: /**
72: * @param mixed[] $properties
73: */
74: public static function __set_state(array $properties): Type
75: {
76: return new self(
77: $properties['type'],
78: );
79: }
80:
81: }
82: