TS 5.8 TypeError: Cannot read properties of undefined (reading 'kind')
🔎 Search Terms
TypeError: Cannot read properties of undefined (reading 'kind')
🕗 Version & Regression Information
- This changed between versions 5.7.3 and 5.8.2
- This changed in commit or PR https://github.com/microsoft/TypeScript/pull/60052
⏯ Playground Link
https://www.typescriptlang.org/dev/bug-workbench/?ts=5.8.2#code/KYDwDg9gTgLgBDAnmYcDKMCGNUF44DeAsAFBxyYBccAdgK4C2ARsFANynlPUDOMUASxoBzDiQC+Y0qEiw4AYwA2mHjzgAVYH2Jk4PYDAzZgACj7HqRnAEoC4zgi3x8J4NUw1E1uLgB8hB3IAM2g4E3kIGj44AG0Aa2BEABo4ADdMRTpgAF04CCC4AHkmACtgeRgAOmAafgEtV2tvHXJWhAALAR5K-UMsHBMWttb4xOzqdMzgJMDW8WsxNvtdSVJl0iA
💻 Code
export type State = {
a: number;
b: string;
};
export class Test{
setState(state: State){}
test = (e: any) => {
for (const [key, value] of Object.entries(e)) {
this.setState({
[key]: value,
});
}
};
}
🙁 Actual behavior
running tsc results in a crash:
TypeError: Cannot read properties of undefined (reading 'kind')
🙂 Expected behavior
No crash is expected, some type errors should be found instead.
Additional information about the issue
No response
I'm also hitting this. Here's the MRE: https://www.typescriptlang.org/play/?#code/C4TwDgpgBAwg9gO2AQwJYIgJwDwGkIgDOUEAHsBAgCbGHCboDmAfFALxQDeAUFFANr4QUdFCGEAugC4oAIzhwANhGQIA3NwC+3bgGNEdKPoR1VwGfCRoMOAEQAzBbagAfKLdnJMt1hx59HOBl6AFcIABpeOS8Ze2RFQgitHXsQhF1gVEQoKhAEZABbVF08AmIyCmpaeiZmAAp7VEw6GXFw6MYZAFlkMFKidvklFQRmAEoLRBR0LH7CVn8oZWAoTAhCEMVzWCnrWfFWNzSqCEaMKnYoY9OZqg0ox0woOuNDfgBrAnaAN3iwiSgcHsHQAdJQaus6mMxlwonxUMC6gBCNYbLYw1GbFZ+ASfEDSKC-RRhKCaDR8PgQBLQTFbD4EAEcIlhcmknR8NbAEKYBCrdZYjTabi5fJFXR1BxOdoYADuUB6YDq-H4krgtnaoQgEnaKs83nacWpEgk0KAA
Wondering what the status of this one is and if the linked PR can be reviewed / merged?
It seems the compiler fails to use variables declared by a tuple as index keys. For those of you looking for a workaround in the meantime: redefine your tuples to rather be normal variables (using Object.keys and Object.values for above example) instead.
Workaround
Before
for (const [key, value] of Object.entries(data)) {
data = { [key]: value };
}
After
for (const key in data) {
data = { [key]: data[key] };
}
An alternative, potentially a bit more type-friendly workaround (e.g. when using noUncheckedIndexedAccess ) is to keep using Object.entries() but destructure the entries in a separate statement.
Before
for (const [key, value] of Object.entries(data)) {
console.log(key, value);
}
After
for (const entry of Object.entries(data)) {
const [key, value] = entry;
console.log(key, value);
}