/ mlflow / server / js / eslint-plugin / rules / no-const-object-record-string.js
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  };