github azjezz/psl 4.0.0
Noise 4.0.0

7 hours ago

Psl Noise - 4.0.0

This release marks a major update for the PHP Standard Library, introducing several breaking changes aimed at improving strictness, consistency, and developer experience. The library is now much stricter in its type handling and serialization, and the static analysis has been migrated to a more powerful tool.

🚀 Breaking Changes

💥 Psl\Result\wrap() No Longer Unwraps Nested Results

To reduce surprising behavior, Psl\Result\wrap() will no longer automatically unwrap a Result instance returned from within the wrapped closure. It will now consistently wrap the closure's return value in a Success object, even if that value is itself a Result.

Before:

$result = Psl\Result\wrap(fn() => Psl\Result\wrap(fn() => 'hello'));
// $result is Success('hello')

After:

$result = Psl\Result\wrap(fn() => Psl\Result\wrap(fn() => 'hello'));
// $result is Success(Success('hello'))

💥 JSON Serialization for Collections

The JSON serialization for Map and Set collections has been changed to provide a more natural and predictable representation.

  • Psl\Collection\Map and Psl\Collection\MutableMap now serialize to a JSON object ({...}) in all cases, even when empty or when containing sequential integer keys. This ensures a consistent key-value structure.
  • Psl\Collection\Set and Psl\Collection\MutableSet now serialize to a JSON array ([...]), which better represents a collection of unique values.

💥 Removal of IO Intersection Interfaces

A large number of intersection interfaces in the Psl\IO and Psl\File namespaces have been removed to simplify the component's hierarchy. These interfaces were combinations of other interfaces (e.g., CloseReadHandleInterface as CloseHandleInterface&ReadHandleInterface).

Developers should now use union types or explicit interface checks where needed. For example, instead of type-hinting CloseReadHandleInterface, use CloseHandleInterface&ReadHandleInterface.

💥 Psl\sequence() Function Removed

The Psl\sequence() function, which returned the last argument it received, has been removed as it provided little practical value.

✨ New Features

Psl\Type\container()

A new container<Tk, Tv> type has been added to assert that a value is an iterable with specific key and value types. Unlike iterable(), it will coerce the value to an array.

Psl\Type\int_range()

The new int_range(int $min, int $max) type allows asserting that a value is an integer within a specified range. It supports the same coercions as the int() type.

Psl\Type\always_assert()

This new type wrapper ensures that the inner type is always asserted, even during coercion. This is useful for disabling coercion on a per-type basis.

Psl\Iter\search_with_keys() and search_with_keys_opt()

These functions provide the ability to search an iterable using a predicate that receives both the key and the value, returning the value of the first match.

♻️ Refactoring and Improvements

  • Static Analysis Migration: The project has migrated from Psalm to Mago for static analysis, resulting in stricter type checking and improved code quality. Many internal @psalm-suppress annotations have been removed.
  • Improved Type Inference: PHPDoc annotations across Dict, Iter, Regex, and Vec have been enhanced with conditional types. This allows static analysis tools to infer more precise types, especially for non-empty arrays and regex match results, reducing the need for user-land assertions.
  • Generic PHPDoc Tags: Psalm-specific tags like @psalm-pure have been replaced with the more generic @pure to reduce dependency on a single tool.

⬆️ Dependency Updates

  • mago has been updated to 1.0.0-beta.15.
  • actions/checkout has been bumped from v4 to v5 in GitHub Actions.
  • Other minor dependency updates.

🤝 New Contributors


Full Changelog: 3.3.0...4.0.0

Don't miss a new psl release

NewReleases is sending notifications on new releases.