Kirill
Но там будет ошибка в LoginResponse потом, т.к. getResponseClassName должен возвращать TResponse, а у тебя там захардкожен LoginResponse
Kirill
в данном примере кода работать будет, однако сама иерархия кривая и строчка /** @var Request<TResponse> $request */ будет работать до тех пор, пока TResponse внутри instanceof LoginResponse
Вадим
подскажите где почитать нормально про дженерики?
Вадим
CoreRequestInterface<TResponse> что означают вот эти угловые скобки? CoreRequestInterface содержит TResponse? CoreRequestInterface использует TResponse? CoreRequestInterface работает с TResponse?
Вадим
как мне сказать что CoreBaseHandler::handle должен принимать любые реквесты интерфейса CoreRequestInterface и отдавать респонс который содержится в ревесте?
Вадим
:)
Kirill
типа: @template TArg of Response @param Request<TArg> $request @return TArg
Kirill
дженерики - это просто возможность передать конкретный тип как аргумент)
Юра
вообщем
Юра
Type<A> не связан никак с Type<B>
Юра
читай про generic variance
Kirill
ну потому что другие аргументы, да
Юра
но я не смог победить
Юра
пофиг
Kirill
да не пофигу)
Юра
нужно явно говорить
Kirill
а ещё мы забываем про ковариантные параметры)
Kirill
и про call-side variance)
Юра
вопрос по дефолту как в пхпстане
Юра
если параметр под дефолту invariant то Type<A> != Type<B> даже если A instanceof B
Kirill
B - интерфейс, A - реализация
Kirill
$values = list<B>
Kirill
ты запросто туда можешь пихать реализации
Kirill
в чём проблема?
Kirill
я просто не понимаю твоего "никак не связан"
Kirill
связан напрямую же, если они в цепочке наследования
Вадим
но теперь CoreRequestInterface должен быть дженериком
Kirill
у тебя не параметр зависит от типа, а сам класс)
Kirill
ну вот это уже выглядит как более реально к тому, что тебе нужно
Kirill
ты передаёшь аргумент интерфейса, а должен вернуться респонз из этого интерфейса
Kirill
точнее объект респонза из класса, который возвращается в методе интерфейса, который должен быть инстанс оф КорБазРеквест
Вадим
ты передаёшь аргумент интерфейса, а должен вернуться респонз из этого интерфейса
я передаю аргументом интерфейс а должен вернуться объект из класса, имя которого знает реализация интерфейса
Kirill
а интерфейс выглядит примерно так, судя по твоему скрину: /** @template-covariant TResponse of ResponseInteface */ interface CoreRequestInterface { /** @return class-string<TResponse> */ public function getReponseClassName(): string; }
Kirill
влом нормально форматировать код в телеге)
Юра
$values = list<B>
Какой тип у values?
Kirill
Какой тип у values?
list<B> написал же
Kirill
а, понял про что ты
Kirill
/** @var list<B> */ $values = []; $values[] = new A(); // class A implements B
Юра
Угу
Юра
И теперь сделай $c = $values[0]
Kirill
ну $c будет B
Юра
Да
Kirill
только ещё есть такая штука как self-out)
Юра
Но ковариантность это не про B
Юра
Это про List<B>
Kirill
т.е. можно во время вызова подменить аргумент темплейта
Юра
И List<A>
Kirill
и сделать list<A> после вызова
Kirill
https://phpstan.org/writing-php-code/phpdocs-basics#change-type-of-current-object-after-calling-a-method
Юра
У него короче стан ругается что типы не совпадают так как они разные
Kirill
Но ковариантность это не про B
так ты написал что list<B> != list<A>
Юра
Потому что List<A> не равняется по дефолту лист Б
Kirill
ну в твоём варианте Type<B> != Type<A>
Kirill
Потому что List<A> не равняется по дефолту лист Б
так я написал, что если инстанс оф, то является
Юра
Ну так посмотри пхпстан коллекций пхпшных
Kirill
на то что у него стоит Request без типа, а темплейт аргумент захардкожен
Kirill
решается добавлением 1ой строчки
Юра
Напиши два листа с такими типами и попробуй покопировать туда сюда
Вадим
тэк, вроде в песочнице ошибки ушли, пойду в проект ребята, спасибо!
Kirill
это очевидно
Kirill
что ты хочешь этим доказать-то?
Юра
что ты хочешь этим доказать-то?
https://phpstan.org/r/5f1be4fc-a1d7-4039-b5eb-a2c27312d411
Юра
Что по умолчанию ты не можешь заменить MyArray<ParentClass> на MyArray<ChildClass>
Юра
Хоть ChildClass instanceof ParentClass
Юра
Что по умолчанию ты не можешь заменить MyArray<ParentClass> на MyArray<ChildClass>
потому что по умолчанию MyArray<ParentClass> != MyArray<ChildClass> не важно instanceof или нет