-
-
Notifications
You must be signed in to change notification settings - Fork 87
Description
Thank you for the awesome work on this library. Valinor is super useful and makes it much easier to deal with external data in a strongly typed project.
I am facing an issue since 0.11 added the following restriction:
It is now mandatory to list all possible class-types that can be inferred by the mapper. This change is a step towards the library being able to deliver powerful new features such as compiling a mapper for better performance.
Currently, this change makes interface inference incompatible with generic classes, as Valinor will not accept a return type like class-string<Foo<A>|Foo<B>> (rightfully, as this is not a valid type) or 'Foo<A>'|'Foo<B>'.
To give some context, I'm trying to map a discriminated union, but the discriminator is on the parent node.
The source looks like this:
{
"type": "string",
"node": "..."
}And the model looks like this:
/** @template T */
interface RootInterface {}
class Root implements RootInterface {
public function __construct(
/** @var T */
NodeInterface $node,
){}
}
interface NodeInterface {}
class NodeA implements NodeInterface {}
class NodeB implements NodeInterface {}Due to the position of the discriminator, I can not directly infer the type of the nested node: I must infer the type of the root node.
It seems that supporting a return type that consists of a union of strings in this case would fix the issue, as I could type the mapper like this:
/** @return 'Root<NodeA>'|'Root<NodeB>' */
fn (string $type) => ...Here is a full example of my use-case: https://gist.github.com/arnaud-lb/535d89874ed719265f66bc19a88b5fb0