TypeScript icon indicating copy to clipboard operation
TypeScript copied to clipboard

'in' does not remove undefined from indexed value (with noUncheckedIndexedAccess)

Open Sainan opened this issue 10 months ago • 2 comments

🔎 Search Terms

in operator, noUncheckedIndexedAccess

🕗 Version & Regression Information

Tested 5.8.2 and 5.9.0-dev.20250310

⏯ Playground Link

https://www.typescriptlang.org/play/?noUncheckedIndexedAccess=true&ts=5.8.2#code/MYewdgzgLgBAhgJwQLhmArgWwEYFMEDaAujALwwECMANDAEy0DMRA3AFCiSwCWAJgB6oMOfGXrtuAMxgAKPvxjcw8JAEoYAbzYwdMTtBiC0WPAjGJC81tt36QAG1wA6eyADmM-qvYBfNkA

💻 Code

With an array:

const arr: number[] = [1, 2, 3];
const idx: number = 2;
if (idx in arr) {
    const x: number = arr[idx];
    console.log(x);
}

With a map/object:

const map: Record<string, number> = { a: 1 };
const key: string = "a";
if (key in map) {
    const x: number = map[key];
    console.log(x);
}

🙁 Actual behavior

Type 'number | undefined' is not assignable to type 'number'.
  Type 'undefined' is not assignable to type 'number'.

🙂 Expected behavior

Expected 'in' operator to guarantee that the result of indexing is not undefined in this branch.

Additional information about the issue

No response

Sainan avatar Mar 10 '25 09:03 Sainan

Duplicate of #54241.

MartinJohns avatar Mar 10 '25 10:03 MartinJohns

There is some inconsistency here since https://github.com/microsoft/TypeScript/pull/57847 though: TS playground

Andarist avatar Mar 10 '25 10:03 Andarist

@Andarist Would this fix this issue too? Image

// TYPE NARROWING CORRECTLY
const key = 'data';
if (key in obj) {
	const v = obj[key];
} else {
	const v = obj[key];
}

// DUMB
const other = { key: 'data' };
if (other.key in obj) {
	const v = obj[other.key];
} else {
	const v = obj[other.key];
}

cole-abbeduto-particle avatar Jun 03 '25 20:06 cole-abbeduto-particle