webmozarts / assert

Assertions to validate method input/output with nice error messages.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Misuse of `empty` psalm type

zerkms opened this issue · comments

Assert::isEmpty is typed as @psalm-assert empty $value
Assert::notEmpty is typed as @psalm-assert !empty $value

I think both are wrong.

https://psalm.dev/docs/annotating_code/type_syntax/atomic_types/

empty - a type that represents a lack of type - not just a lack of type information (that's where mixed is useful) but where there can be no type. A good example is the type of the empty array []. Psalm types this as array<empty, empty>.

So I believe there is no psalm type currently available to express empty'ness or non-empty'ness in the php values meaning.

Oops, accidentally closed, reopening.

Seems coherent:
https://psalm.dev/r/7972caa66e

When you expect empty, Psalm will reject any value.
When you expect !empty, Psalm will accept any value.

It would have been a different story if we were able to do this though:
@psalm-assert ($value is string : empty-string : ($value is array ? empty-array : mixed) $value

Unfortunately, it only works with returns right now

@orklah

When you expect empty, Psalm will reject any value.

This is wrong, '', [], 0 etc are valid empty values (as per the Assert::isEmpty semantics).

Psalm's empty (lack of) type and php's empty() function have different incompatible semantics, even though they are named the same.

Ok, wait a second, it looks like psalm combines empty with the already currently known type, and produces a context-specific intersection.

In that case I'm indeed wrong.

Closing this as invalid, thanks!