Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improved support for enum-string types #3807

Merged
merged 5 commits into from
Feb 5, 2025

Conversation

zonuexe
Copy link
Contributor

@zonuexe zonuexe commented Feb 5, 2025

@@ -696,7 +698,7 @@ static function (string $variance): TemplateTypeVariance {
if (count($genericTypes) === 2) { // iterable<KeyType, ValueType>
return new IterableType($genericTypes[0], $genericTypes[1]);
}
} elseif (in_array($mainTypeName, ['class-string', 'interface-string'], true)) {
} elseif (in_array($mainTypeName, ['class-string', 'interface-string', 'enum-string'], true)) {
Copy link
Contributor Author

@zonuexe zonuexe Feb 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of adding this elseif clause, another idea is to add another clause.

-		} elseif (in_array($mainTypeName, ['class-string', 'interface-string'], true)) {
+		} elseif ($mainTypeName === 'enum-string') {
 			if (count($genericTypes) === 1) {
 				$genericType = $genericTypes[0];
-				if ($genericType->isObject()->yes() || $genericType instanceof MixedType) {
+				if ($genericType->isEnum()->yes() || $genericType instanceof MixedType) {
 					return new GenericClassStringType($genericType);
 				}
			}

However, Psalm simply equates the three.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to do TypeCombinator::intersect($genericType, new ObjectType(UnitEnum::class)). You can then test it with enum-string<object> and also enum-string<SomeInterface>.

@@ -696,7 +698,7 @@ static function (string $variance): TemplateTypeVariance {
if (count($genericTypes) === 2) { // iterable<KeyType, ValueType>
return new IterableType($genericTypes[0], $genericTypes[1]);
}
} elseif (in_array($mainTypeName, ['class-string', 'interface-string'], true)) {
} elseif (in_array($mainTypeName, ['class-string', 'interface-string', 'enum-string'], true)) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to do TypeCombinator::intersect($genericType, new ObjectType(UnitEnum::class)). You can then test it with enum-string<object> and also enum-string<SomeInterface>.

@zonuexe zonuexe force-pushed the feature/enum-string branch from 5eb8099 to 5eaf06a Compare February 5, 2025 09:55
@zonuexe zonuexe marked this pull request as draft February 5, 2025 10:04
@zonuexe zonuexe marked this pull request as ready for review February 5, 2025 10:05
@phpstan-bot
Copy link
Collaborator

This pull request has been marked as ready for review.

@ondrejmirtes ondrejmirtes merged commit 471b818 into phpstan:2.1.x Feb 5, 2025
13 checks passed
@ondrejmirtes
Copy link
Member

Thank you!

@zonuexe zonuexe deleted the feature/enum-string branch February 5, 2025 10:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make enum-string equivalent to class-string<UnitEnum>
3 participants