Skip to content

⬅️ Back to Table of Contents

πŸ“„ no-generated-empty-object-type

πŸ“Š Analysis Summary

Metric Count
πŸ”§ Functions 4
πŸ“¦ Imports 4

πŸ“š Table of Contents

πŸ› οΈ File Location:

πŸ“‚ packages/eslint-plugin/src/rules/no-generated-empty-object-type.ts

πŸ“€ Default Export

export default createRule({ ... })
Property Value
name 'no-generated-empty-object-type'
meta.type 'problem'
meta.docs.description 'Disallow type operations that resolve to the "empty object" type'
meta.docs.recommended 'strict'
meta.docs.requiresTypeChecking true
meta.messages.noGeneratedEmptyObjectType 'This type resolves to {}, the empty object type. This was likely not intentional.'
meta.schema []
defaultOptions []

Entry point: create β€” documented under Functions.


πŸ“¦ Imports

Name Source
TSESTree @typescript-eslint/utils
AST_NODE_TYPES @typescript-eslint/utils
createRule ../util
getParserServices ../util

Functions

create(context: any): { TSIntersectionType: (node: TSESTree.Node) => void; TSType…

Parameters:

  • context any

Returns: { TSIntersectionType: (node: TSESTree.Node) => void; TSTypeReference(node: any): void; }

Calls:

  • getParserServices (from ../util)
  • services.program.getTypeChecker
  • tsutils.isObjectType
  • tsutils.isObjectFlagSet
  • checker.getPropertiesOfType
  • checker.getIndexInfosOfType
  • type.getCallSignatures
  • type.getConstructSignatures
  • checker.isTypeAssignableTo
  • checker.getNumberType
  • isEmptyObjectType
  • type.isUnion
  • type.types.some
  • containsEmptyObjectType
  • services.getTypeAtLocation
  • context.report
  • checkNode

Internal Comments:

// Types still awaiting type arguments, such as `Record<T, unknown>` (x3)
// inside a generic declaration, also have no members yet. (x3)

Code
create(context) {
    const services = getParserServices(context);
    const checker = services.program.getTypeChecker();

    function isEmptyObjectType(type: ts.Type) {
      return (
        tsutils.isObjectType(type) &&
        !tsutils.isObjectFlagSet(
          type,
          ts.ObjectFlags.Class | ts.ObjectFlags.Interface,
        ) &&
        checker.getPropertiesOfType(type).length === 0 &&
        checker.getIndexInfosOfType(type).length === 0 &&
        type.getCallSignatures().length === 0 &&
        type.getConstructSignatures().length === 0 &&
        // Types still awaiting type arguments, such as `Record<T, unknown>`
        // inside a generic declaration, also have no members yet.
        checker.isTypeAssignableTo(checker.getNumberType(), type)
      );
    }

    function containsEmptyObjectType(type: ts.Type) {
      return (
        isEmptyObjectType(type) ||
        (type.isUnion() && type.types.some(isEmptyObjectType))
      );
    }

    function checkNode(node: TSESTree.Node) {
      if (containsEmptyObjectType(services.getTypeAtLocation(node))) {
        context.report({
          node,
          messageId: 'noGeneratedEmptyObjectType',
        });
      }
    }

    return {
      TSIntersectionType: checkNode,
      TSTypeReference(node) {
        if (
          node.typeArguments &&
          node.parent.type !== AST_NODE_TYPES.TSIntersectionType
        ) {
          checkNode(node);
        }
      },
    };
  }

Internal helpers

Declared inside another function in this file.

isEmptyObjectType(type: ts.Type): any

Parameters:

  • type ts.Type

Returns: any

Calls:

  • tsutils.isObjectType
  • tsutils.isObjectFlagSet
  • checker.getPropertiesOfType
  • checker.getIndexInfosOfType
  • type.getCallSignatures
  • type.getConstructSignatures
  • checker.isTypeAssignableTo
  • checker.getNumberType

Internal Comments:

// Types still awaiting type arguments, such as `Record<T, unknown>` (x3)
// inside a generic declaration, also have no members yet. (x3)

Code
function isEmptyObjectType(type: ts.Type) {
      return (
        tsutils.isObjectType(type) &&
        !tsutils.isObjectFlagSet(
          type,
          ts.ObjectFlags.Class | ts.ObjectFlags.Interface,
        ) &&
        checker.getPropertiesOfType(type).length === 0 &&
        checker.getIndexInfosOfType(type).length === 0 &&
        type.getCallSignatures().length === 0 &&
        type.getConstructSignatures().length === 0 &&
        // Types still awaiting type arguments, such as `Record<T, unknown>`
        // inside a generic declaration, also have no members yet.
        checker.isTypeAssignableTo(checker.getNumberType(), type)
      );
    }

containsEmptyObjectType(type: ts.Type): any

Parameters:

  • type ts.Type

Returns: any

Calls:

  • isEmptyObjectType
  • type.isUnion
  • type.types.some
Code
function containsEmptyObjectType(type: ts.Type) {
      return (
        isEmptyObjectType(type) ||
        (type.isUnion() && type.types.some(isEmptyObjectType))
      );
    }

checkNode(node: TSESTree.Node): void

Parameters:

  • node TSESTree.Node

Returns: void

Calls:

  • containsEmptyObjectType
  • services.getTypeAtLocation
  • context.report
Code
function checkNode(node: TSESTree.Node) {
      if (containsEmptyObjectType(services.getTypeAtLocation(node))) {
        context.report({
          node,
          messageId: 'noGeneratedEmptyObjectType',
        });
      }
    }

Generated by Syntax Scribe