Skip to content

Commit

Permalink
Add support to create type with multiple string values
Browse files Browse the repository at this point in the history
This is to help create phpstan types of string constants
  • Loading branch information
sunkan committed Nov 5, 2024
1 parent b66bd81 commit d071e71
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/ValueObject/Type.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ final class Type
private string $namespace = '';
/** @var Type[] */
private array $types = [];
private bool $noneValidTypeHint = false;

/**
* @param list<string> $types
Expand All @@ -38,6 +39,16 @@ public static function fromIdentifier(Identifier $identifier): self
return self::fromString($identifier->toString());
}

public static function enumString(string ...$values): self
{
$self = new self('');
$self->noneValidTypeHint = true;
foreach ($values as $value) {
$self->types[] = new self("'$value'");
}
return $self;
}

public static function fromString(string $type): self
{
if (!trim($type, '? ')) {
Expand Down Expand Up @@ -158,6 +169,10 @@ public function addUnion(Type|string $type): void

public function getTypeHint(bool $renderUnion = false): ?string
{
if ($this->noneValidTypeHint) {
return null;
}

if (count($this->types) > 1) {
if ($renderUnion) {
$typeHint = [];
Expand Down
27 changes: 27 additions & 0 deletions tests/ValueObject/TypeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -326,4 +326,31 @@ public function testMixedWithNullable(): void
$this->assertSame('mixed|object', $type->getDocBlockTypeHint());
$this->assertSame('mixed|object', $type->getTypeHint(true));
}

public function testEnumStringValues(): void
{
$type = Type::enumString('value1', 'value2', 'value3');
$this->assertSame("'value1'|'value2'|'value3'", $type->getDocBlockTypeHint());
$this->assertNull($type->getTypeHint());
$this->assertNull($type->getTypeHint(true));
}

public function testEnumStringValueNullable(): void
{
$type = Type::enumString('value1', 'value2', 'value3');
$type->addUnion('null');
$this->assertSame("'value1'|'value2'|'value3'|null", $type->getDocBlockTypeHint());
$this->assertNull($type->getTypeHint());
$this->assertNull($type->getTypeHint(true));
}

public function testEnumStringValueNullableAndClass(): void
{
$type = Type::enumString('value1', 'value2', 'value3');
$type->addUnion('null');
$type->addUnion(\BackedEnum::class);
$this->assertSame("'value1'|'value2'|'value3'|BackedEnum|null", $type->getDocBlockTypeHint());
$this->assertNull($type->getTypeHint());
$this->assertNull($type->getTypeHint(true));
}
}

0 comments on commit d071e71

Please sign in to comment.