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

indexing optional attributes fails when indexing with a key that is keyof interface #52895

Closed
sezanzeb opened this issue Feb 21, 2023 · 5 comments
Labels
Duplicate An existing issue was already created

Comments

@sezanzeb
Copy link

sezanzeb commented Feb 21, 2023

Bug Report

πŸ”Ž Search Terms

  • TS2532
  • keyof
  • undefined
  • interface
  • optional
  • Object is possibly 'undefined'

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about keyof

⏯ Playground Link

https://www.typescriptlang.org/play?ts=5.0.0-dev.20230221#code/JYOwLgpgTgZghgYwgAhgezcg3gWAFDKHIBGcUA-AFzIgCuAtsdPgL774y0gJjBogk4ALwAU+IsgCOtAB7V0aADTiiMYBAA2AE2oBrCAE80MVBnwBKagDc0wLdhWFgJkdJkBtNZq0BdZAEIAXkDkLi0INRAILXMHAgkiBH4AZzQNCAA6DTQAc1dZT3VtPwBqZABGc0dkNjxaoA

πŸ’» Code

interface foo {
    bar?: number
}

function baz(
    qux: foo,
    field: keyof foo
): void {
    if (qux[field] !== undefined) {
        console.log(qux[field] + 1)
    }
}

πŸ™ Actual behavior

Object is possibly 'undefined' error

πŸ™‚ Expected behavior

To work just like if field is set to 'bar' instead of keyof foo

interface foo {
    bar?: number
}

function baz(
    qux: foo
): void {
    const field = 'bar';
    if (qux[field] !== undefined) {
        console.log(qux[field] + 1)
    }
}
@MartinJohns
Copy link
Contributor

Duplicate of #10530. Type narrowing does not occur for indexed access forms e[k] where k is not a literal. Just store it in a local const variable.

@RyanCavanaugh RyanCavanaugh added the Duplicate An existing issue was already created label Feb 21, 2023
@sezanzeb
Copy link
Author

That works, thanks!

interface foo {
    bar?: number
}

function baz(
    qux: foo,
    field_: keyof foo
): void {
    const field = field_;

    if (qux[field] !== undefined) {
        console.log(qux[field] + 1)
    }
}

@sezanzeb
Copy link
Author

sezanzeb commented Feb 22, 2023

This does not work if there are multiple optional fields:

https://www.typescriptlang.org/play?ts=5.0.0-dev.20230221#code/JYOwLgpgTgZghgYwgAhgezcg3gWAFDKHIBGcUAjAPwBcyIArgLbHT5ElkBMNdTLU+AL758MeiARhgaEBwBeACjZEAjvQAetdGgA0ywjGAQANgBMA+rQDWEAJ5oYqDPgCUtAG5pgp7PuQIZAGcwVCMzZABeUJMLAG4RAiJgRwU1dQBtQxiAXWQAQgio8VMIQxAIUxdfRPZCAJBAtGMIADpjNABzVI1MsNNcgGpkchc-YTxBIA

interface foo {
    bar1?: number
    bar2?: number
}

function baz(
    qux: foo,
    field_: keyof foo
): void {
    const field = field_;

    if (qux[field] !== undefined) {
        console.log(qux[field] + 1)
    }
}

same error, "Object is possibly 'undefined'"

@sezanzeb
Copy link
Author

sezanzeb commented Feb 22, 2023

Oh, you were probably talking about storing qux[field] in a const. That works for the second case as well:

interface foo {
    bar1?: number
    bar2?: number
}

function baz(
    qux: foo,
    field: keyof foo
): void {
    const blub = qux[field];
    if (blub !== undefined) {
        console.log(blub + 1)
    }
}

@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