Skip to content

⬅️ Back to Table of Contents

📄 dot-notation

📊 Analysis Summary

Metric Count
🔧 Functions 1
📦 Imports 8
📊 Variables & Constants 1
📑 Type Aliases 2

📚 Table of Contents

🛠️ File Location:

📂 packages/eslint-plugin/src/rules/dot-notation.ts

📤 Default Export

export default createRule<Options, MessageIds>({ ... })
Property Value
name 'dot-notation'
meta.type 'suggestion'
meta.docs.description 'Enforce dot notation whenever possible'
meta.docs.extendsBaseRule true
meta.docs.frozen true
meta.docs.recommended 'stylistic'
meta.docs.requiresTypeChecking true
meta.fixable baseRule.meta.fixable
meta.hasSuggestions baseRule.meta.hasSuggestions
meta.messages baseRule.meta.messages
meta.schema [ { type: 'object', additionalProperties: false, properties: { allowIndexSignaturePropertyAccess: { type: 'boolean', ...

Entry point: create — documented under Functions.


📦 Imports

Name Source
TSESTree @typescript-eslint/utils
AST_NODE_TYPES @typescript-eslint/utils
InferMessageIdsTypeFromRule ../util
InferOptionsTypeFromRule ../util
createRule ../util
getModifiers ../util
getParserServices ../util
getESLintCoreRule ../util/getESLintCoreRule

Variables & Constants

Name Type Kind Value Exported
defaultOptions Options const [ { allowIndexSignaturePropertyAccess: false, allowKeywords: true, allowPatte...

Functions

create(context: any, [options]: any): { MemberExpression(node: TSESTree.MemberExpression): void; }

Parameters:

  • context any
  • [options] any

Returns: { MemberExpression(node: TSESTree.MemberExpression): void; }

Calls:

  • baseRule.create
  • getParserServices (from ../util)
  • services.program.getTypeChecker
  • tsutils.isCompilerOptionEnabled
  • services.program.getCompilerOptions
  • services.getSymbolAtLocation
  • services .getTypeAtLocation(node.object) .getNonNullableType() .getProperties() .find
  • getModifiers (from ../util)
  • propertySymbol?.getDeclarations
  • services .getTypeAtLocation(node.object) .getNonNullableType
  • checker.getIndexInfosOfType
  • indexInfos.some
  • tsutils.isTypeFlagSet
  • rules.MemberExpression

Internal Comments:

// for perf reasons - only fetch symbols if we have to (x2)

Code
create(context, [options]) {
    const rules = baseRule.create(context);
    const services = getParserServices(context);
    const checker = services.program.getTypeChecker();
    const allowPrivateClassPropertyAccess =
      options.allowPrivateClassPropertyAccess;
    const allowProtectedClassPropertyAccess =
      options.allowProtectedClassPropertyAccess;
    const allowIndexSignaturePropertyAccess =
      (options.allowIndexSignaturePropertyAccess ?? false) ||
      tsutils.isCompilerOptionEnabled(
        services.program.getCompilerOptions(),
        'noPropertyAccessFromIndexSignature',
      );

    return {
      MemberExpression(node: TSESTree.MemberExpression): void {
        if (
          (allowPrivateClassPropertyAccess ||
            allowProtectedClassPropertyAccess ||
            allowIndexSignaturePropertyAccess) &&
          node.computed
        ) {
          // for perf reasons - only fetch symbols if we have to
          const propertySymbol =
            services.getSymbolAtLocation(node.property) ??
            services
              .getTypeAtLocation(node.object)
              .getNonNullableType()
              .getProperties()
              .find(
                propertySymbol =>
                  node.property.type === AST_NODE_TYPES.Literal &&
                  propertySymbol.escapedName === node.property.value,
              );
          const modifierKind = getModifiers(
            propertySymbol?.getDeclarations()?.[0],
          )?.[0].kind;
          if (
            (allowPrivateClassPropertyAccess &&
              modifierKind === ts.SyntaxKind.PrivateKeyword) ||
            (allowProtectedClassPropertyAccess &&
              modifierKind === ts.SyntaxKind.ProtectedKeyword)
          ) {
            return;
          }
          if (propertySymbol == null && allowIndexSignaturePropertyAccess) {
            const objectType = services
              .getTypeAtLocation(node.object)
              .getNonNullableType();
            const indexInfos = checker.getIndexInfosOfType(objectType);
            if (
              indexInfos.some(info =>
                tsutils.isTypeFlagSet(info.keyType, ts.TypeFlags.StringLike),
              )
            ) {
              return;
            }
          }
        }
        rules.MemberExpression(node);
      },
    };
  }

Type Aliases

Options

type Options = InferOptionsTypeFromRule<typeof baseRule>;

MessageIds

type MessageIds = InferMessageIdsTypeFromRule<typeof baseRule>;

Generated by Syntax Scribe