-
-
Notifications
You must be signed in to change notification settings - Fork 9.8k
[TypeInfo] Fix template key-type for array #62738
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
base: 7.3
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR fixes a bug where template keys constrained to array-key (which is int|string) incorrectly threw an InvalidArgumentException when used as array key types. The fix unwraps template types to access their bounds before validation.
Key Changes:
- Added unwrapping logic for template types in array key validation to check the bound type rather than the template wrapper
- Added comprehensive test cases covering template keys with
array-keybounds - Updated the
DummyCollectionfixture with template annotations forTKeyandTValue
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
src/Symfony/Component/TypeInfo/Type/CollectionType.php |
Added logic to unwrap TemplateType and validate its bound when checking array key types |
src/Symfony/Component/TypeInfo/Tests/TypeResolver/StringTypeResolverTest.php |
Added test cases for arrays and lists with template types, plus a negative test for invalid template key bounds |
src/Symfony/Component/TypeInfo/Tests/Fixtures/DummyCollection.php |
Added template annotations for TKey (constrained to array-key) and TValue to support new test cases |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| $keyType = $this->getCollectionKeyType(); | ||
|
|
||
| if ($keyType instanceof TemplateType) { | ||
| $keyType = $keyType->getWrappedType(); | ||
| } | ||
|
|
||
| $keyTypes = $keyType instanceof UnionType ? $keyType->getTypes() : [$keyType]; | ||
|
|
||
| foreach ($keyTypes as $type) { | ||
| if (!$type instanceof BuiltinType || !\in_array($type->getTypeIdentifier(), [TypeIdentifier::INT, TypeIdentifier::STRING], true)) { | ||
| throw new InvalidArgumentException(\sprintf('"%s" is not a valid array key type.', (string) $keyType)); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We must be able to handle
- Union of scalars
- Union of template types, such as
TFoo|TBar. - Template type that is a union
- Template type that is scalar
To handle every case, maybe we can do the following:
$keyType = $this->getCollectionKeyType();
foreach ($keyType->traverse(false) as $t) { // to traverse composite but not wrapped (because nullable, collection, etc are not valid)
if ($t instanceof UnionType) {
continue;
}
if (($t instanceof BuiltinType || $t instanceof TemplateType) && $t->isIdentifiedBy(TypeIdentifier::INT, TypeIdentifier::STRING) {
continue;
}
// others types, such as intersection, nullable types, etc are not valid
throw new InvalidArgumentException(\sprintf('"%s" is not a valid array key type.', (string) $keyType));
}
#62388 broke type detection for template keys for array:
Above example currently throws an exception
Symfony\Component\TypeInfo\Exception\InvalidArgumentException: "TKey" is not a valid array key type.even thoughTKeyis a type ofarray-key(int|string).This PR fixes this by getting the wrapped type when dealing with a template type when checking if a valid array key type is provided.