-
Notifications
You must be signed in to change notification settings - Fork 659
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
Cannot assert parameter to be template container of other parameter #4339
Comments
I found these snippets: https://psalm.dev/r/49995ab4a2<?php
class A {}
class B {}
/**
* @template T
*/
class Container {
}
/**
* @template T
* @param class-string<T> $class
* @param class-string<Container<T>> $container
*/
function wrap(string $class, string $container): void {
}
/**
* @template-extends Container<A>
*/
class AC extends Container {
}
/**
* @template-extends Container<B>
*/
class BC extends Container {
}
wrap(A::class, AC::class);
wrap(A::class, BC::class);
|
I think something like this should work: https://psalm.dev/r/f407561f3e (but doesn't). |
I found these snippets: https://psalm.dev/r/f407561f3e<?php
class A {}
class B {}
/**
* @template T
*/
class Container {
}
/**
* @template T
* @template TC of Container<T>
* @param class-string<T> $_class
* @param class-string<TC> $_container
*/
function wrap(string $_class, string $_container): void {}
/**
* @template-extends Container<A>
*/
class AC extends Container {
}
/**
* @template-extends Container<B>
*/
class BC extends Container {
}
wrap(A::class, AC::class);
wrap(A::class, BC::class);
|
I don't think that's really possible, though I could see this being supported: https://psalm.dev/r/07d0b932d5 |
I found these snippets: https://psalm.dev/r/07d0b932d5<?php
class A {}
class B {}
/**
* @template T
*/
class Container {
}
/**
* @template T
* @param class-string<T> $_class
* @return callable(class-string<Container<T>>):void
*/
function wrap(string $_class): callable {
return function(string $container) : void {};
}
/**
* @template-extends Container<A>
*/
class AC extends Container {
}
/**
* @template-extends Container<B>
*/
class BC extends Container {
}
wrap(A::class)(AC::class);
wrap(A::class)(BC::class);
|
1 similar comment
I found these snippets: https://psalm.dev/r/07d0b932d5<?php
class A {}
class B {}
/**
* @template T
*/
class Container {
}
/**
* @template T
* @param class-string<T> $_class
* @return callable(class-string<Container<T>>):void
*/
function wrap(string $_class): callable {
return function(string $container) : void {};
}
/**
* @template-extends Container<A>
*/
class AC extends Container {
}
/**
* @template-extends Container<B>
*/
class BC extends Container {
}
wrap(A::class)(AC::class);
wrap(A::class)(BC::class);
|
Yeah, to be honest I wasn't quite sure if the type system would allow this, given that there might be some tricky edge cases.
Interesting approach, though it wouldn't help with the functions I'm typing right now as I can't change their signature because they are part of a stable API. I'm fine with closing this, just figured it might be worth reporting in case it's a bug :) |
I found these snippets: https://psalm.dev/r/07d0b932d5<?php
class A {}
class B {}
/**
* @template T
*/
class Container {
}
/**
* @template T
* @param class-string<T> $_class
* @return callable(class-string<Container<T>>):void
*/
function wrap(string $_class): callable {
return function(string $container) : void {};
}
/**
* @template-extends Container<A>
*/
class AC extends Container {
}
/**
* @template-extends Container<B>
*/
class BC extends Container {
}
wrap(A::class)(AC::class);
wrap(A::class)(BC::class);
|
Loading https://psalm.dev/r/49995ab4a2 with 4.9.2 gives me
so this "feature" now works 🚀 |
I found these snippets: https://psalm.dev/r/49995ab4a2<?php
class A {}
class B {}
/**
* @template T
*/
class Container {
}
/**
* @template T
* @param class-string<T> $class
* @param class-string<Container<T>> $container
*/
function wrap(string $class, string $container): void {
}
/**
* @template-extends Container<A>
*/
class AC extends Container {
}
/**
* @template-extends Container<B>
*/
class BC extends Container {
}
wrap(A::class, AC::class);
wrap(A::class, BC::class);
|
Hello.
I'm trying to Psalm-type an API of an event dispatcher where you pass the event class as class-string as well as the listener as class-string. The listener is a template class with the event as template argument.
I simplified the example into a container that wraps an element and wrote this snippet: https://psalm.dev/r/49995ab4a2
The goal is to assert that the
$container
argument ofwrap
is aContainer<T>
and not aContainer<object>
but it looks like Psalm does not bother mixed template types. See the last line.Is this a limitation of how far Psalm can work with the type system or am I doing something that is not solvable by types?
PS: if anyone has a better title, shoot.
Cheers ✌️
The text was updated successfully, but these errors were encountered: