Return type of … is expected to not be nullable/built-in/

survik1
Člen | 4
+
0
-

Ahoj,

řeším problém, u kterého mi Nette/DI 3.0 resp. 3.1 hází vidle pod nohy.

Máme aplikaci konfigurovanou přes env. Z mnoha důvodů se před postavením kontejneru vytváří třída, která tyto ENV validuje, otypuje, vyhází optionals a zprostředkovává je zbytku aplikace. Většina volání je přímočarých, problém je u následující syntaxe

parameters:
    clusters:
        cluster1:
            options: \Application\Config\Configuration::getInstance()::getKafka("name1")::getOptions()`
            topics:
                ...
        ...
    ...

Což v pozadí je

    /**
     * @return Kafka|null
     */
    public function getKafka(string $cluster): ?Kafka
    {
        return $this->kafkaCollection->offsetGet($cluster);
    }

Od verze 3.0 ale pro typovaný návratový typ dostávám chybu uvedenou v titulku. Od verze 3.1 již není přípustná ani anotace @return. Když typ i anotaci smažu, nikdo si nestěžuje, ale přijde mi to jako cesta zpět. Je nějaké jiné systémové řešení? Zápis přes config z migračního plánu pro nette/di 3.1 je pro mě nepoužitelný, protože jak říkám, tenhle objekt se staví ještě přes vznikem kontejneru.

Marek Bartoš
Nette Blogger | 1260
+
0
-

Asi by se dalo říct, že je v tomhle případě DI zbytečně přísné. A jelikož nezná conditional types, tak nemůže s jistotou říct, jestli se vrací Kafka nebo null. Možná však typy interně potřebuje znát, netuším.

Nejjednodušší řešení pro tebe by bylo mít metodu, co null nevrací, takže třeba takto:

public function getKafkaOrThrow(string $cluster): Kafka
{
	return $this->getKafka($cluster) ?? throw new Exception("Kafka cluster '$cluster' not found.");
}
David Grudl
Nette Core | 8218
+
+1
-

DI k té anotaci @return přistupuje velmi volně, vlastně uřízne všechno za |, takže vidí jen Kafka. Naopak nativní anotace bere přesně, takže vidí union type ?Kafka. Upravím to, aby nullable ignoroval.

Ještě mě napadá, že by mohl v takovém případě použít operátor ?->.

v dev verzích by to už mělo fungovat

survik1
Člen | 4
+
0
-

Marek Bartoš napsal(a):

Asi by se dalo říct, že je v tomhle případě DI zbytečně přísné. A jelikož nezná conditional types, tak nemůže s jistotou říct, jestli se vrací Kafka nebo null. Možná však typy interně potřebuje znát, netuším.

Nejjednodušší řešení pro tebe by bylo mít metodu, co null nevrací, takže třeba takto:

public function getKafkaOrThrow(string $cluster): Kafka
{
	return $this->getKafka($cluster) ?? throw new Exception("Kafka cluster '$cluster' not found.");
}

Ona právě nullable být může, nepotřebujeme ji mít definovanou na všech prostředích. Zpravidla na testovacích prostředích se testuje jen omezená sada funkcí a způsob, jakým pracujeme s ENV nám umožňuje, že se pro takové prostředí distribuuje jen omezená sada ENV místo kompletního výčtu s „fake hodnotami“.

survik1
Člen | 4
+
0
-

David Grudl napsal(a):

DI k té anotaci @return přistupuje velmi volně, vlastně uřízne všechno za |, takže vidí jen Kafka. Naopak nativní anotace bere přesně, takže vidí union type ?Kafka. Upravím to, aby nullable ignoroval.

Ještě mě napadá, že by mohl v takovém případě použít operátor ?->.

v dev verzích by to už mělo fungovat

Děkuji, funguje to. Osobně jsem hledal něco jako ?::