Skip to content

⬅️ Back to Table of Contents

πŸ“„ prefer-readonly-parameter-types

πŸ“Š Analysis Summary

Metric Count
πŸ”§ Functions 2
πŸ“¦ Imports 9
πŸ“‘ Type Aliases 2

πŸ“š Table of Contents

πŸ› οΈ File Location:

πŸ“‚ packages/eslint-plugin/src/rules/prefer-readonly-parameter-types.ts

πŸ“€ Default Export

export default createRule<Options, MessageIds>({ ... })
Property Value
name 'prefer-readonly-parameter-types'
meta.type 'suggestion'
meta.docs.description 'Require function parameters to be typed as readonly to prevent accidental mutation of inputs'
meta.docs.requiresTypeChecking true
meta.messages.shouldBeReadonly 'Parameter should be a read only type.'
meta.schema [ { type: 'object', additionalProperties: false, properties: { allow: { ...readonlynessOptionsSchema.properties.allow...
defaultOptions [ { allow: readonlynessOptionsDefaults.allow, checkParameterProperties: true, ignoreInferredTypes: false, treatMethod...

Entry point: create β€” documented under Functions.


πŸ“¦ Imports

Name Source
TSESTree @typescript-eslint/utils
AST_NODE_TYPES @typescript-eslint/utils
TypeOrValueSpecifier ../util
createRule ../util
getParserServices ../util
isTypeBrandedLiteralLike ../util
isTypeReadonly ../util
readonlynessOptionsDefaults ../util
readonlynessOptionsSchema ../util

Functions

create(context: any, [ { allow, checkParameterProper…: any): { [x: string]: (node: TSESTree.ArrowFunctionExpression | TS…

Parameters:

  • context any
  • [ { allow, checkParameterProperties, ignoreInferredTypes, treatMethodsAsReadonly, }, ] any

Returns: { [x: string]: (node: TSESTree.ArrowFunctionExpression | TSESTree.FunctionDeclaration | TSESTree.FunctionExpression | TSESTree.TSCallSignatureDeclaration | TSESTree.TSConstructSignatureDeclaration | TSESTree.TSDeclareFunction | TSESTree.TSEmptyBodyFunctionExpression | TSESTree.TSFunctionType | TSESTree.TSMethodSignature) => void; }

Calls:

  • getParserServices (from ../util)
  • services.program.getTypeChecker
  • services.esTreeNodeToTSNodeMap.get
  • checker.getTypeFromTypeNode
  • services.getTypeAtLocation
  • [ AST_NODE_TYPES.ArrowFunctionExpression, AST_NODE_TYPES.FunctionDeclaration, AST_NODE_TYPES.FunctionExpression, AST_NODE_TYPES.TSCallSignatureDeclaration, AST_NODE_TYPES.TSConstructSignatureDeclaration, AST_NODE_TYPES.TSDeclareFunction, AST_NODE_TYPES.TSEmptyBodyFunctionExpression, AST_NODE_TYPES.TSFunctionType, AST_NODE_TYPES.TSMethodSignature, ].join
  • getParameterType
  • isTypeReadonly (from ../util)
  • isTypeBrandedLiteralLike (from ../util)
  • context.report

Internal Comments:

// Get type from annotation node to preserve aliasSymbol (x2)

Code
create(
    context,
    [
      {
        allow,
        checkParameterProperties,
        ignoreInferredTypes,
        treatMethodsAsReadonly,
      },
    ],
  ) {
    const services = getParserServices(context);

    function getParameterType(
      actualParam:
        | TSESTree.ArrayPattern
        | TSESTree.AssignmentPattern
        | TSESTree.Identifier
        | TSESTree.ObjectPattern
        | TSESTree.RestElement,
    ): ts.Type {
      if (actualParam.typeAnnotation?.typeAnnotation) {
        // Get type from annotation node to preserve aliasSymbol
        const checker = services.program.getTypeChecker();
        const tsTypeNode = services.esTreeNodeToTSNodeMap.get(
          actualParam.typeAnnotation.typeAnnotation,
        ) as ts.TypeNode;
        return checker.getTypeFromTypeNode(tsTypeNode);
      }
      return services.getTypeAtLocation(actualParam);
    }

    return {
      [[
        AST_NODE_TYPES.ArrowFunctionExpression,
        AST_NODE_TYPES.FunctionDeclaration,
        AST_NODE_TYPES.FunctionExpression,
        AST_NODE_TYPES.TSCallSignatureDeclaration,
        AST_NODE_TYPES.TSConstructSignatureDeclaration,
        AST_NODE_TYPES.TSDeclareFunction,
        AST_NODE_TYPES.TSEmptyBodyFunctionExpression,
        AST_NODE_TYPES.TSFunctionType,
        AST_NODE_TYPES.TSMethodSignature,
      ].join(', ')](
        node:
          | TSESTree.ArrowFunctionExpression
          | TSESTree.FunctionDeclaration
          | TSESTree.FunctionExpression
          | TSESTree.TSCallSignatureDeclaration
          | TSESTree.TSConstructSignatureDeclaration
          | TSESTree.TSDeclareFunction
          | TSESTree.TSEmptyBodyFunctionExpression
          | TSESTree.TSFunctionType
          | TSESTree.TSMethodSignature,
      ): void {
        for (const param of node.params) {
          if (
            !checkParameterProperties &&
            param.type === AST_NODE_TYPES.TSParameterProperty
          ) {
            continue;
          }

          const actualParam =
            param.type === AST_NODE_TYPES.TSParameterProperty
              ? param.parameter
              : param;

          if (ignoreInferredTypes && actualParam.typeAnnotation == null) {
            continue;
          }

          const type = getParameterType(actualParam);
          const isReadOnly = isTypeReadonly(services.program, type, {
            allow,
            treatMethodsAsReadonly: !!treatMethodsAsReadonly,
          });

          if (!isReadOnly && !isTypeBrandedLiteralLike(type)) {
            context.report({
              node: actualParam,
              messageId: 'shouldBeReadonly',
            });
          }
        }
      },
    };
  }

Internal helpers

Declared inside another function in this file.

getParameterType(actualParam: | TSESTree.ArrayPattern | TSESTree.Assi…): ts.Type

Parameters:

  • actualParam | TSESTree.ArrayPattern | TSESTree.AssignmentPattern | TSESTree.Identifier | TSESTree.ObjectPattern | TSESTree.RestElement

Returns: ts.Type

Calls:

  • services.program.getTypeChecker
  • services.esTreeNodeToTSNodeMap.get
  • checker.getTypeFromTypeNode
  • services.getTypeAtLocation

Internal Comments:

// Get type from annotation node to preserve aliasSymbol (x2)

Code
function getParameterType(
      actualParam:
        | TSESTree.ArrayPattern
        | TSESTree.AssignmentPattern
        | TSESTree.Identifier
        | TSESTree.ObjectPattern
        | TSESTree.RestElement,
    ): ts.Type {
      if (actualParam.typeAnnotation?.typeAnnotation) {
        // Get type from annotation node to preserve aliasSymbol
        const checker = services.program.getTypeChecker();
        const tsTypeNode = services.esTreeNodeToTSNodeMap.get(
          actualParam.typeAnnotation.typeAnnotation,
        ) as ts.TypeNode;
        return checker.getTypeFromTypeNode(tsTypeNode);
      }
      return services.getTypeAtLocation(actualParam);
    }

Type Aliases

Options

type Options = [
  {
    allow?: TypeOrValueSpecifier[];
    checkParameterProperties?: boolean;
    ignoreInferredTypes?: boolean;
    treatMethodsAsReadonly?: boolean;
  },
];

MessageIds

type MessageIds = 'shouldBeReadonly';

Generated by Syntax Scribe