Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merging object-like arrays on imported type does not work #8984

Open
mstilkerich opened this issue Dec 22, 2022 · 6 comments
Open

Merging object-like arrays on imported type does not work #8984

mstilkerich opened this issue Dec 22, 2022 · 6 comments

Comments

@mstilkerich
Copy link
Contributor

Using intersection types, it is possible to extend array shapes as described here.

This works fine:

<?php

/**
 * @psalm-type SaveData = array{name: string}
 * @psalm-type ExtSaveData = SaveData & array{id:string}
 */
Class Test1 {
}

However, if I want to do the same when one of the types is imported from another file, I get an error from psalm:

/********** FILE Test1.php **********/
<?php

/**
 * @psalm-type SaveData = array{name: string}
 */
Class Test1 {
}

/********** FILE Test2.php **********/
<?php

/**
 * @psalm-import-type SaveData from Test1
 * @psalm-type ExtSaveData = SaveData & array{id:string}
 */
Class Test2 {
}

This will produce the following error:

ERROR: InvalidDocblock - Test2.php:8:1 - Intersection types must be all objects, Psalm\Type\Atomic\TKeyedArray provided (see https://psalm.dev/008)
/**
 * @psalm-import-type SaveData from Test1
 * @psalm-type ExtSaveData = SaveData & array{id:string}
 */
Class Test2 {
@jack-worman
Copy link
Contributor

I have encountered this as well :(

@kkmuffme
Copy link
Contributor

Looks like this is the same as #9603 - see (temporary) "as" fix on that issue

@asgrim
Copy link

asgrim commented Oct 17, 2023

Another very similar example: https://psalm.dev/r/82a8ee14d5

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/82a8ee14d5
<?php

namespace A {
  /**
   * @psalm-type AType = array{test: string}
   */
  class AAA {
  }
}

namespace B {
  /**
   * @psalm-import-type AType from \A\AAA
   * @psalm-type BType = array{anotherTest: string}
   * @psalm-type Compound = AType&BType
   */
  class BBB {
    /**
     * @param Compound $type
     */
    public function useCompoundType($type): void
    {
       /** @psalm-trace $type */
       return;
    }
  }
}
Psalm output (using commit 67d6468):

ERROR: InvalidDocblock - 17:3 - The intersection type must not mix array and object types!

ERROR: UndefinedDocblockClass - 19:15 - Docblock-defined class, interface or enum named B\Compound does not exist

@discordier
Copy link
Contributor

Another one, with minimalistic annotation.
https://psalm.dev/r/bce2b8edcb

Copy link

I found these snippets:

https://psalm.dev/r/bce2b8edcb
<?php

/**
 * @psalm-type TBaseConfiguration=array{type?: string, ...<string, mixed>}
 * @psalm-type TConfiguration=array{name: string}&TBaseConfiguration
 */
class Working2 {}

/** @psalm-type TBaseConfiguration=array{type?: string, ...<string, mixed>} */
class BaseClass {}

/**
 * @psalm-import-type TBaseConfiguration from BaseClass
 * @psalm-type TConfiguration=array{name: string}&TBaseConfiguration
 */
class BrokenDueToImportedType1 {}
Psalm output (using commit 08afc45):

ERROR: InvalidDocblock - 16:1 - Intersection types must be all objects or all keyed array.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants