I'll use it a lot if they'll be namespaced. It avoids name-collision using the existing ecosystem and we already use lots of "uses" in our codes. When Enums came to the party, they came namespaced as traits, classes and interfaces. The last 2 represent types, concrete and abstract. User defined types are nothing more than types, so I think the way to gois to keep it namespaced as well.
About the type compatibility, covariance and contravariance, let's say I define some type inside my package: // File: C1.php => My package code namespace N1; typedef MyString = string|Stringable|\Symfony\Component\String\UnicodeString ; typedef MyBool = null|bool; typedef BigNumeric = int|float|\Brick\Math\BigNumber; class C1 { protected function myQuestionableFunction(MyString $str1): MyBool { //... } protected function myQuestionableFunction2(null|C1 $str1): ScalarNumeric { //... } } // File: C2.php => On the project of those who are using my package namespace N2; typedef ScalarNumeric = int|float; typedef Falsy = null|false; class C1 extends C2 { protected function myQuestionableFunction(string|Stringable|\Symfony\Component\String\UnicodeString $str1): Falsy { //... } protected function myQuestionableFunction2(Falsy|C1 $str1): ScalarNumeric { //... } } I propose that this code should be valid code, because, in the end, these *typedef's*, are just synonyms. *Note:* By the way, I propose to use the C/C++ keyword, which is *typedef* and dropping the syntax* "type MyType = [string, null];",* which differs too from how typehints are used and do not add any benefits *.* -- Erick