Hi Jorg, Apologies for missing your first message, It slipped past me.
The problem is typing a value whose valid set is a few specific primitives you don't own and shouldn't model nominally: a flag that comes back as the int 1, 2 or 3 from a database or C extension, an HTTP status, or an 'asc'|'desc' that exists only at one API boundary. Enums fit when you own the type and want a named domain model with backing and methods. They're a poor fit when the values originate outside your control, or when you need a structural building block rather than a new named type, because an enum then forces you to define, import and convert to and from a nominal type for what is only "one of these primitive values." Enums stay the right tool for domain modelling; this covers the cases they handle badly, the way `int` and an `Age` value object coexist. > I would prefer type aliases, such as Robert’s proposal from last year, as a foundation before considering this direction: https://wiki.php.net/rfc/typed-aliases I'd love type aliases too, but they're orthogonal, and for the case you care about they build on this feature. An alias names a type that must already be expressible: `type Direction = 'asc'|'desc'` requires `'asc'|'desc'` to be a valid type first. So literal types are the prerequisite for aliasing the very `'asc'|'desc'` you'd want to name. > This is exactly my concern. Literal types are useful in TypeScript, but they are also often directly overused. I do not think PHP should encourage the same pattern. > My concern is that the RFC encourages public APIs like function f(1|2|3 $x) or function sort('asc'|'desc' $direction), where magic scalar values become part of the runtime API instead of being represented by a properly domain modeled entity. A tool existing doesn't mandate its misuse. Enums remain available and are still the recommendation for domain modelling; nothing here changes that. Reaching a genuinely expressive type system means considering many features: generics, literals, array shapes, typed arrays, aliases, ranges, and more, most of which developers already rely on today through PHPDoc and static analysers because they add value. We can't land them in one massive overhaul; each needs its own focused discussion, and several (negated types, conditional types) would look out of place in PHP on their own. Literals are one of the foundational pieces the rest build on. > Modern AI-assisted engineering makes semantic naming even more important. Inline literal types such as 1|2|3 or 'asc'|'desc' provide less semantic signal than named concepts such as enums or type aliases. This can make code harder not only for humans, but also for AI tools that rely heavily on names and surrounding context. However, I'm aware that this secondary argument is not very plausible in this group. I'm not sure about this. `function move('up'|'down'|'left'|'right' $d)` states its valid inputs right at the signature. `function move(Direction $d)` requires resolving what `Direction` is, class, interface or enum, and what it permits, and how to obtain an instance of it before you do anything. The literal form arguably carries more local signal, for a human or an AI. > Language features should be evaluated from the long-term user and API-design perspective, not only from the static-analysis perspective. From that perspective, I think this RFC approaches the problem from the wrong side. Agreed, and that's the motivation here. The feature is API-design driven, with the future scope spelling it out: array shapes, integer ranges and similar build directly on literal types as their foundation. That's the long-term type-system frame I'd like the RFC judged on, rather than viewing it as a static-analysis convenience. Cheers, Seifeddine
