Psalm: Documenting properties of object-like arrays

Created on 9 Jul 2020  Â·  6Comments  Â·  Source: vimeo/psalm

We currently use phpDoc nested types to document and type object-like arrays throughout our various codebases, e.g:

/**
 * @param array  $options {
 *     @type string   $build_path    Absolute file system path to the static asset output folder.
 *                                   Optional; defaults to the manifest file's parent folder.
 *     @type string   $handle        The handle to use when enqueuing the style/script bundle.
 *                                   Optional; defaults to the basename of the build folder's parent folder.
 *     @type array    $scripts       Script dependencies. Optional.
 *     @type array    $styles        Style dependencies. Optional.
 * }
 */

To better match Psalm's typing, we're looking at instead switching to the object-like array syntax that Psalm supports. This would gain us the typing, but it appears there's no way to retain the human-readable descriptions at the same time with this.

The convention in TypeScript that I've seen is usually something like:

type Foo = {
    // This describes the `some` property.
    some?: value;

    /** Or maybe an inline doc comment */
    bar: Quux;
};

These don't work in Psalm (and the doc-comment style would break anyway), but a similar style could perhaps be applied. Perhaps something like:

/**
 * @return array{
 *     // Optional docs?
 *     optional?: string,
 *
 *     # Or this?
 *     bar: int
 * }
 */

Is there a recommended solution to this that I've just missed? 🤔

enhancement

Most helpful comment

Yo dawg, I heard you like comments, so I put a comment inside your comment, so you can comment while you comment :)

Personally I don't think this is something worth supporting as you can put whatever text you want in the phpDoc's description. But if other tools choose to support, I'll eventually add it to PHPStan too...

All 6 comments

/**
 * @return array{
 *     // Optional docs?
 *     optional?: string,
 * }
 */

seems like a good solution – though @TysonAndre, @OndrejMirtes may also have opinions

I doubt that // would cause problems - lines starting with that could be filtered out easily when processing type lines. There's no current uses for #, but I'd rather just have one way to comment in case a use case for it is found in the future for phpdoc (symbols, etc)

I'd rather just have one way to comment

Yeah, me too

Yo dawg, I heard you like comments, so I put a comment inside your comment, so you can comment while you comment :)

Personally I don't think this is something worth supporting as you can put whatever text you want in the phpDoc's description. But if other tools choose to support, I'll eventually add it to PHPStan too...

Hi @rmccue, as a workaround, you can bypass this by using @psalm-param:

/**
 * @param array  $options {
 *     @type string   $build_path    Absolute file system path to the static asset output folder.
 *                                   Optional; defaults to the manifest file's parent folder.
 *     @type string   $handle        The handle to use when enqueuing the style/script bundle.
 *                                   Optional; defaults to the basename of the build folder's parent folder.
 *     @type array    $scripts       Script dependencies. Optional.
 *     @type array    $styles        Style dependencies. Optional.
 * }
 *
 * @psalm-param array{build_path?:string,handle?:string,scripts?:array<string>} $options
 */

To better match Psalm's typing, we're looking at instead switching to the object-like array syntax that Psalm supports. This would gain us the typing, but it appears there's no way to retain the human-readable descriptions at the same time with this.

You can use PHPDoc, for documenting, and Pslam for analyzing.

Certainly, we _could_ write it twice, but I'm trying to ease Psalm adoption internally. :) Both phpDoc and Psalm are doing the same thing, which is describing a shape, so it makes sense to unify those approaches. If we can't, phpDoc is essentially a superset of Psalm's capabilities (albeit with much, much better typing), so it'll win that battle.

I don't love comments-inside-comments either FWIW, but without some sort of symbol to disambiguate text from types, not sure how to avoid parsing errors easily and consistently. The suggestions of // and # are just because those are PHP comment operators already, so at least they're somewhat familiar in meaning to devs as "the following is human-readable text" (although, # isn't used often).

Was this page helpful?
0 / 5 - 0 ratings