I'm getting ts object is possibly undefined on the line groupedImports[id].push(item), with groupedImports[id] underlined.
I test that hits exists and has length > 0 prior to this clause, and create groupedImports[] if needed.
I don't understand why ts thinks groupedImports[id] might be undefined.
// Dictionary is from @reduxjs/redux-toolkit
interface ImportError {
text: string,
args: string,
}
interface Import {
status: string,
"@import_id": string,
"@import_time": Date,
"@import_file": string,
errors: Array<ImportError>
}
let groupedImports: Dictionary<Import[]> = {}
hits.forEach( (item) => {
const id = item['@import_id']
if (id) {
if (!(id in groupedImports)) {
groupedImports[id] = [];
}
groupedImports[id].push(item);
}
})
See @reduxjs/redux-toolkit for the Dictionary type.
CodePudding user response:
Thanks to Jeff Bowman, something about the definition of Dictionary I was using (from react toolkit)..
Adding type Dictionary<T> = Record<string, T>; resolved it.
CodePudding user response:
Redux Toolkit's Dictionary is declared to be much like Record, except that the values are possibly undefined. That's why you're encountering that problem, and why my naïve attempt at defining Dictionary didn't reproduce it.
if (id) {
if (!(id in groupedImports)) {
groupedImports[id] = [];
}
groupedImports[id].push(item);
}
In this code, you can establish that groupedImports[id] will never be undefined by the time push runs, but TypeScript is still prepared for the possibility that groupedImports[id] is undefined. Notably, this is true even if you remove the if guard and unconditionally set the value to [], as in this playground link.
As alluded to in this SO question and described by MartinJohns in microsoft/TypeScript#41612:
Type narrowing does not occur for indexed access forms
e[k]wherekis not a literal.
Other than using Record<string, Import[]> directly or redefining Dictionary to be non-undefined in all keys, you can use a non-null assertion operator (postfix !) to tell TypeScript not to worry about the possibility of undefined.
groupedImports[id]!.push(item);
// ^
