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

allow_unknown_fields is not taken into account #12

Open
JeroenBakker opened this issue Apr 25, 2023 · 1 comment
Open

allow_unknown_fields is not taken into account #12

JeroenBakker opened this issue Apr 25, 2023 · 1 comment

Comments

@JeroenBakker
Copy link

JeroenBakker commented Apr 25, 2023

Hi there,

I often parse things such as API responses or other JSON decoded payloads with the allow_unknown_fields parameter set to true.
This allows me to be forwards compatible with any fields that may be added in the future, or lets me assert the rest of a shape conditionally based on other data.

But PHPStan thinks it knows the whole shape of an array with this code:

Type\shape(['foo' => Type\string()], allow_unknown_fields: true)->assert($body);

\PHPStan\dumpType($body); // Dumped type: array{foo: string}

// Call to method Psl\Type\TypeInterface<array<string, string>>::matches() with array{foo: string} will always evaluate to false. 
if (Type\shape(['bar' => Type\string()], allow_unknown_fields: true)->matches($body)) {
    \PHPStan\dumpType($body); // Dumped type: *NEVER* 
}

I would expect a type like array&hasOffsetValue('foo', string) instead.

I tried digging into the code to see if I could offer a PR to add/fix this, but I have no clue how to achieve this 😅

@JeroenBakker
Copy link
Author

Just wanted to mention that I was able to work around this by explicitly including any other fields I want to use later on as optional in the original assert (which seems a pretty obvious workaround in hindsight):

Type\shape([
    'foo' => Type\string(),
    'bar' => Type\optional(Type\string()),
], allow_unknown_fields: true)->assert($responseBody);

\PHPStan\dumpType($body); // Dumped type: array{foo: string, bar?: string}

But as the structure of the data gets more complex and contains many fields this would become very verbose contain a lot of duplication in all the checks.

But for now this works okay for me.

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

1 participant