no-const-object-record-string.js
1 const ERROR = 'NO_CONST_OBJECT_RECORD_STRING'; 2 3 module.exports = { 4 meta: { 5 fixable: 'code', 6 messages: { 7 [ERROR]: 8 'Do not use `Record<string, *> when declaring a non-empty constant object because it will remove type checking of properties, resulting in unsafe access. Either specify a stricter type for the keys of the object or use `satisfies Record<string, *>` if you want to infer the keys.', 9 }, 10 }, 11 12 create(context) { 13 const sourceCode = context.getSourceCode(); 14 15 return { 16 VariableDeclarator(node) { 17 if ( 18 node.init?.type !== 'ObjectExpression' || 19 // Ignore empty objects because their type cannot be inferred 20 node.init?.properties?.length === 0 || 21 node.id?.typeAnnotation?.typeAnnotation === undefined || 22 node.id?.typeAnnotation?.typeAnnotation?.typeName?.name !== 'Record' || 23 node.id?.typeAnnotation?.typeAnnotation?.typeArguments?.params?.[0]?.type !== 'TSStringKeyword' 24 ) { 25 return; 26 } 27 28 const typeAnnotation = node.id.typeAnnotation; 29 const typeAnnotationText = sourceCode.getText(typeAnnotation.typeAnnotation); 30 31 context.report({ 32 fix(fixer) { 33 return [ 34 // Remove the `: Record<string, *>` type annotation 35 fixer.remove(typeAnnotation), 36 // Add the ` satisfies Record<string, *>` type annotation 37 fixer.insertTextAfter(node, ` satisfies ${typeAnnotationText}`), 38 ]; 39 }, 40 node, 41 messageId: ERROR, 42 }); 43 }, 44 }; 45 }, 46 };