Comparing a direct property read off a Record<string, X>-typed object with ===/!== crashes the compiler with an internal error, for any value type X (tested with both string and object/record-shaped values). The crash disappears if the property read is first assigned to a local variable and the variable is compared instead — same runtime semantics, different compile result.
Minimal Demo
/** @type {Record<string, string>} */
const R = { a: "x", b: "y" };
console.log(R.a === R.a);
Output
[...]/test.js:3:13 - error SC9001: internal compiler error: in %init.0: recordKeyGet receiver: expected record, got dyn — please report this
2 | const R = { a: "x", b: "y" };
3 | console.log(R.a === R.a); // internal compiler error: recordKeyGet receiver: expected record, got dyn
| ^
4 |
[...]/test.js:3:21 - error SC9001: internal compiler error: in %init.0: recordKeyGet receiver: expected record, got dyn — please report this
2 | const R = { a: "x", b: "y" };
3 | console.log(R.a === R.a); // internal compiler error: recordKeyGet receiver: expected record, got dyn
| ^
4 |
2 errors.
Minimal Workaround
/** @type {Record<string, string>} */
const R = { a: "x", b: "y" };
const a = R.a;
console.log(a === a); // compiles fine
Comparing a direct property read off a
Record<string, X>-typed object with===/!==crashes the compiler with an internal error, for any value typeX(tested with bothstringand object/record-shaped values). The crash disappears if the property read is first assigned to a local variable and the variable is compared instead — same runtime semantics, different compile result.Minimal Demo
Output
Minimal Workaround