Skip to content

Guarding against object value not being undefined fails when object value is typed with Partial<T> | undefined #53148

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

Closed
bencooper222 opened this issue Mar 7, 2023 · 3 comments
Labels
Duplicate An existing issue was already created

Comments

@bencooper222
Copy link

Bug Report

🔎 Search Terms

  • full partial type guard union
  • enum as keys to interface with values possibly undefined or
  • undefined guard not compatible with Partial<T> | undefined

🕗 Version & Regression Information

I reproduced this on TS4.5, 4.8, 4.9, and 5.1.0-dev.20230306

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about Partials and undefined type guards

⏯ Playground Link

https://www.typescriptlang.org/play?ts=5.1.0-dev.20230306#code/JYOwLgpgTgZghgYwgAgCoQM5mQbwFDLIBGANnABYBcyWUoA5gNwHIwD2b1tDzAvnnlCRYiFAjbg4oaLhYBtANYQAnlzB0Q9ALrUACnChhgcEgB50WAHzIAPsgCuIACYQY0p3wHiQWZGyIAVtTeYFIgMgC8soRw1PiEhKQU1ABEcCkANCyE7JzIKUSZLLxZvMx43r7qyqjkmChRcmmZ+YVa5exQyAAUldhgbKhQyn4wyNW19QCU0cjAY93+AXIDQ8payACEUY4ubuFOM-EJlWwkEAB0JGz0i4Erg8NaF0nkU8yE-PxAA

💻 Code

interface Test {
  blah: string;
  foo: string;
}

interface container {
  [key: string]: Partial<Test> | undefined;
}

const obj: container = {
  a: {
    blah: "a",
    foo: "b",
  },
};

const tryThese = ["a", "b"];

for (const toTry of tryThese) {
  if (obj[toTry] != undefined) {
    // next line has error "Object is possibly 'undefined'.(2532)"
    console.log(obj[toTry].blah);
  }
}

🙁 Actual behavior

I specifically check if obj[toTry] is not undefined but TS still throws an error that obj[toTry] is potentially undefined. I suspect this is because Partial<T> is a superset of undefined.

🙂 Expected behavior

I want TS to not throw an error that obj[toTry] is undefined.

@fatcerberus
Copy link

fatcerberus commented Mar 7, 2023

You have to assign obj[toTry] to a variable and test that. It's a known limitation that TS can't narrow expressions of the form obj[key] unless key is a hard-coded literal.

for (const toTry of tryThese) {
    const value = obj[toTry];
    if (value != undefined) {
        console.log(value.blah);  // now it works
    }
}

I suspect this is because Partial<T> is a superset of undefined.

No, Partial<T> only makes properties optional; you can't assign undefined to it.

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Mar 7, 2023
@RyanCavanaugh
Copy link
Member

See #10530

@typescript-bot
Copy link
Collaborator

This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants