Repository: symfony/symfony
File: src/Symfony/Component/TypeInfo/TypeResolver/StringTypeResolver.php (PHP)

Code before:
                    'optional' => $item->optional,
                ];
            }

            return Type::arrayShape(
                $shape,
                $node->sealed,
                $node->unsealedType?->keyType ? $this->getTypeFromNode($node->unsealedType->keyType, $typeContext) : null,
                $node->unsealedType?->valueType ? $this->getTypeFromNode($node->unsealedType->valueType, $typeContext) : null,
            );
        }

        if ($node instanceof ObjectShapeNode) {
            $shape = [];
            foreach ($node->items as $item) {
                $shape[(string) $item->keyName] = [
                    'type' => $this->getTypeFromNode($item->valueType, $typeContext),
                    'optional' => $item->optional,
                ];
            }

            if ([] === $shape) {
                return Type::object();
            }

            return Type::objectShape($shape);
        }

        if ($node instanceof ThisTypeNode) {
            if (null === $typeContext) {
                throw new InvalidArgumentException(\sprintf('A "%s" must be provided to resolve "$this".', TypeContext::class));
            }

            return Type::object($typeContext->getCalledClass());
        }

        if ($node instanceof ConstTypeNode) {
            if ($node->constExpr instanceof ConstFetchNode) {
                $className = match (strtolower($node->constExpr->className)) {
                    'self' => $typeContext->getDeclaringClass(),
                    'static' => $typeContext->getCalledClass(),
                    'parent' => $typeContext->getParentClass(),
                    default => $node->constExpr->className,
                };

                if (!class_exists($className)) {
                    return Type::mixed();
                }

                $types = [];


Review comment (suggestion):
```suggestion
            return $shape ? Type::objectShape($shape) : Type::object();
```

Code after:
                    'optional' => $item->optional,
                ];
            }

            return Type::arrayShape(
                $shape,
                $node->sealed,
                $node->unsealedType?->keyType ? $this->getTypeFromNode($node->unsealedType->keyType, $typeContext) : null,
                $node->unsealedType?->valueType ? $this->getTypeFromNode($node->unsealedType->valueType, $typeContext) : null,
            );
        }

        if ($node instanceof ObjectShapeNode) {
            $shape = [];
            foreach ($node->items as $item) {
                $shape[(string) $item->keyName] = [
                    'type' => $this->getTypeFromNode($item->valueType, $typeContext),
                    'optional' => $item->optional,
                ];
            }

            return $shape ? Type::objectShape($shape) : Type::object();
        }

        if ($node instanceof ThisTypeNode) {
            if (null === $typeContext) {
                throw new InvalidArgumentException(\sprintf('A "%s" must be provided to resolve "$this".', TypeContext::class));
            }

            return Type::object($typeContext->getCalledClass());
        }

        if ($node instanceof ConstTypeNode) {
            if ($node->constExpr instanceof ConstFetchNode) {
                $className = match (strtolower($node->constExpr->className)) {
                    'self' => $typeContext->getDeclaringClass(),
                    'static' => $typeContext->getCalledClass(),
                    'parent' => $typeContext->getParentClass(),
                    default => $node->constExpr->className,
                };

                if (!class_exists($className)) {
                    return Type::mixed();
                }

                $types = [];

                foreach ((new \ReflectionClass($className))->getReflectionConstants() as $const) {
                    if (preg_match('/^'.str_replace('\*', '.*', preg_quote($node->constExpr->name, '/')).'$/', $const->getName())) {
                        $types[] = Type::fromValue($const->getValue());
                    }