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

Potential risky return of array<int, …> #27

Closed
nickvergessen opened this issue Nov 3, 2023 · 1 comment
Closed

Potential risky return of array<int, …> #27

nickvergessen opened this issue Nov 3, 2023 · 1 comment
Labels
enhancement New feature or request

Comments

@nickvergessen
Copy link
Member

Sample

<?php

/**
 * @return array<int, int>
 */
function takesAnInt1() {
    return [0, 1, 2];
}

/**
 * @return array<int, int>
 */
function takesAnInt2() {
    $a = [0, 1, 2];
    unset($a[1]);
    return $a;
}

/**
 * @return list<int>
 */
function takesAnInt3() {
    return [0, 1, 2];
}

/**
 * @return list<int>
 */
function takesAnInt4() {
    $a = [0, 1, 2];
    unset($a[1]);
    return $a;
}

Psalm output

Only function 4 warns you:

INFO: [LessSpecificReturnStatement](https://psalm.dev/129) - 32:12 - The type 'array{0: 0, 2: 2}' is more general than the declared return type 'list<int>' for takesAnInt4

INFO: [MoreSpecificReturnType](https://psalm.dev/070) - 27:12 - The declared return type 'list<int>' for takesAnInt4 is more specific than the inferred return type 'array{0: 0, 2: 2}'

But function 2 actually returns string keys as well:

<?php

/**
 * @return array<int, int>
 */
function takesAnInt1() {
    return [0, 1, 2];
}

/**
 * @return array<int, int>
 */
function takesAnInt2() {
    $a = [0, 1, 2];
    unset($a[1]);
    return $a;
}

/**
 * @return list<int>
 */
function takesAnInt3() {
    return [0, 1, 2];
}

/**
 * @return list<int>
 */
function takesAnInt4() {
    $a = [0, 1, 2];
    unset($a[1]);
    return $a;
}


var_dump(json_encode(takesAnInt1()));
var_dump(json_encode(takesAnInt2()));
var_dump(json_encode(takesAnInt3()));
var_dump(json_encode(takesAnInt4()));
string(7) "[0,1,2]"
string(13) "{"0":0,"2":2}"
string(7) "[0,1,2]"
string(13) "{"0":0,"2":2}"

I think we should therefore try to discourage using array<int, …> as API return because it's mostlikely a lie 🍰

@nickvergessen nickvergessen added the enhancement New feature or request label Nov 3, 2023
@provokateurin
Copy link
Member

This should already be prevented by #142

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

No branches or pull requests

2 participants