On Fri, Sep 30, 2022 at 11:04 AM Olle Härstedt <olleharst...@gmail.com> wrote:
> 2022-09-29 5:08 GMT+02:00, Hamza Ahmad <office.hamzaah...@gmail.com>: > > Hi Olle, > > > > I appreciate your idea of introducing a similar concept of typedef. > > What if you write an RFC explaining that concept. I can join you > > however in co-authoring this request. > > > > Seriously, I have had issues with writing such type again and again. > > If you look at mixed type, it is indeed an alias of some union types. > > Adding such an option to userland would lead to introduction of > > various type hints. Plus, it will help devs write short hand aliases > > for their intersection types. > > Note that my suggestion here is NOT about a project-global type alias, > but an extension of the existing file-only alias, the use-statement. > This can also explain the lack of reaction. :) Internal devs might > already have consensus on the right way to proceed here, even if > there's no RFC yet. > > Olle > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > > I don't know if file based type aliases make sense, but just spitballing some ideas here. ``` // core php or perhaps some libraries typedef number = int|float; typedef number<number $min> = TypeDef::extend('number', static fn (number $value, number $min) => $value >= $min); typedef number<?number $min, number $max> = TypeDef::extend('number', static fn (number $value, ?number $min, number $max) => ($min === null || $value >= $min) && $value <= $max); typedef even = TypeDef::extend('number<?number $min, number $max>', static fn (number $value) => $value % 2 === 0); typedef positive = number<0>; typedef negative = number<max: 0>; typedef fraction = float<0, 1>; typedef string<int $min> = TypDef::extend('string', static fn (string $value, int $min) => strlen($value) >= $min); typedef string<?int $min, int $max> = TypeDef::extend('string', static fn (string $value, ?int $min, int $max) => length_is_between($value, $min, $max)); typedef regex<string $expression> = TypeDef::extend('string', static fn (string $value, string $regex) => preg_match($regex, $value)); namespace App\Domain; typedef NonEmptyString = string<1>; // minimum length of 1 typedef LimitedString = string<null, 32>; // no minimum length, max length of 32 // or typedef LimitedString = string<max: 32>; as alternative notation with named parameters typedef SomeToken = regex<'/a-z0-9{12}/i'>; // only allows even numbers ranging from -100 to 100 function someFunction(even<-100, 100> $number) {} namespace Elsewhere; use App\Domain\NonEmptyString; use App\Domain\LimitedString; use App\Domain\SomeToken; someFunction(102); // fails `$max` check from `number<min, max>` someFunction(-99); // fails `% 2` check from `even` ``` I tried to use some consistency for the examples, by no means this is what I think it must look like, just making sure the intent of the examples is clear. This would be nothing more than syntactic sugar to what I'd otherwise write in custom objects to validate types and values and ensure type safety. This also doesn't take into account how operators should behave or how autoloading could/should behave.