or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

anti-pattern-prevention-rules.mdarray-object-rules.mdcode-quality-rules.mdcode-style-rules.mddom-browser-rules.mdimport-export-rules.mdindex.mdmodern-javascript-rules.mdplugin-configuration.md
tile.json

array-object-rules.mddocs/

Array and Object Rules

Specialized rules for array and object manipulation, promoting efficient and readable data structure operations.

Capabilities

Array Method Rules

Rules for proper array method usage and patterns.

/**
 * Prevents problematic array callback references
 */
'unicorn/no-array-callback-reference': 'error' | 'warn' | 'off' | [
  'error' | 'warn',
  {
    ignoredFunctions?: string[]; // Default: []
  }
];

/**
 * Prevents array method this argument usage
 */
'unicorn/no-array-method-this-argument': 'error' | 'warn' | 'off';

/**
 * Prevents direct array reverse mutations
 */
'unicorn/no-array-reverse': 'error' | 'warn' | 'off';

/**
 * Requires explicit Array.join() separator
 */
'unicorn/require-array-join-separator': 'error' | 'warn' | 'off';

Usage Examples:

// ❌ Bad - callback reference issues
const numbers = ['1', '2', '3'].map(Number);

// ✅ Good - explicit callback
const numbers = ['1', '2', '3'].map(string => Number(string));

// ❌ Bad - array method this argument
['a', 'b', 'c'].forEach(function(item) {
  console.log(this.prefix + item);
}, { prefix: '>> ' });

// ✅ Good - arrow function or proper binding
const context = { prefix: '>> ' };
['a', 'b', 'c'].forEach(item => {
  console.log(context.prefix + item);
});

// ❌ Bad - mutating reverse
const reversed = originalArray.reverse();

// ✅ Good - non-mutating reverse
const reversed = [...originalArray].reverse();

// ❌ Bad - implicit join separator
const csvLine = columns.join();

// ✅ Good - explicit join separator
const csvLine = columns.join(',');

Array Search and Access Rules

Rules for efficient array searching and element access.

/**
 * Prefers Array.find() over filter()[0] patterns
 */
'unicorn/prefer-array-find': 'error' | 'warn' | 'off' | [
  'error' | 'warn',
  {
    checkFromLast?: boolean; // Default: false
  }
];

/**
 * Prefers Array.some() over find() when checking existence
 */
'unicorn/prefer-array-some': 'error' | 'warn' | 'off';

/**
 * Prefers Array.indexOf() over manual loop for finding indices
 */
'unicorn/prefer-array-index-of': 'error' | 'warn' | 'off';

/**
 * Prefers Array.at() for element access with negative indices
 */
'unicorn/prefer-at': 'error' | 'warn' | 'off' | [
  'error' | 'warn',
  {
    getLastElementFunctions?: string[]; // Default: ['pop', 'shift']
    checkAllIndexAccess?: boolean; // Default: false
  }
];

Usage Examples:

// ❌ Bad - filter()[0] pattern
const user = users.filter(u => u.id === targetId)[0];

// ✅ Good - using find()
const user = users.find(u => u.id === targetId);

// ❌ Bad - using find() just to check existence
if (users.find(u => u.active)) {
  // handle active users
}

// ✅ Good - using some() for existence check
if (users.some(u => u.active)) {
  // handle active users
}

// ❌ Bad - manual loop for index finding
let index = -1;
for (let i = 0; i < items.length; i++) {
  if (items[i] === target) {
    index = i;
    break;
  }
}

// ✅ Good - using indexOf()
const index = items.indexOf(target);

// ❌ Bad - complex negative indexing
const lastItem = array[array.length - 1];
const secondToLast = array[array.length - 2];

// ✅ Good - using at() method
const lastItem = array.at(-1);
const secondToLast = array.at(-2);

Array Flattening and Transformation Rules

Rules for modern array flattening and transformation methods.

/**
 * Prefers Array.flat() over manual flattening
 */
'unicorn/prefer-array-flat': 'error' | 'warn' | 'off' | [
  'error' | 'warn',
  {
    functions?: string[]; // Default: ['concat', 'apply']
  }
];

/**
 * Prefers Array.flatMap() over map().flat() combination
 */
'unicorn/prefer-array-flat-map': 'error' | 'warn' | 'off';

/**
 * Prevents magic numbers in Array.flat() depth
 */
'unicorn/no-magic-array-flat-depth': 'error' | 'warn' | 'off';

/**
 * Prevents unnecessary Array.flat() depth argument
 */
'unicorn/no-unnecessary-array-flat-depth': 'error' | 'warn' | 'off';

/**
 * Prevents unnecessary Array.splice() count argument
 */
'unicorn/no-unnecessary-array-splice-count': 'error' | 'warn' | 'off';

Usage Examples:

// ❌ Bad - manual array flattening
const flattened = [].concat(...arrays);

// ✅ Good - using Array.flat()
const flattened = arrays.flat();

// ❌ Bad - map then flat
const result = items.map(item => item.children).flat();

// ✅ Good - using flatMap()
const result = items.flatMap(item => item.children);

// ❌ Bad - magic number in flat depth
const deepFlattened = nested.flat(3);

// ✅ Good - named constant for depth
const NESTING_DEPTH = 3;
const deepFlattened = nested.flat(NESTING_DEPTH);

// ❌ Bad - unnecessary flat depth
const flattened = array.flat(1); // 1 is default

// ✅ Good - omit default depth
const flattened = array.flat();

// ❌ Bad - unnecessary splice count
array.splice(index); // Removes all elements from index

// ✅ Good - explicit when removing specific count
array.splice(index, 1); // Remove one element

Object Method Rules

Rules for efficient object operations and transformations.

/**
 * Prefers Object.fromEntries() over manual object construction
 */
'unicorn/prefer-object-from-entries': 'error' | 'warn' | 'off' | [
  'error' | 'warn',
  {
    functions?: string[]; // Default: ['fromPairs']
  }
];

/**
 * Prevents unused object properties
 */
'unicorn/no-unused-properties': 'error' | 'warn' | 'off';

Usage Examples:

// ❌ Bad - manual object construction from entries
const obj = {};
for (const [key, value] of entries) {
  obj[key] = value;
}

// ✅ Good - using Object.fromEntries()
const obj = Object.fromEntries(entries);

// ❌ Bad - unused object properties
const config = {
  apiUrl: 'https://api.example.com',
  timeout: 5000,
  retries: 3, // This property is never used
};

// ✅ Good - only used properties
const config = {
  apiUrl: 'https://api.example.com', 
  timeout: 5000,
};

Set and Map Rules

Rules for efficient Set and Map operations.

/**
 * Prefers Set.has() over array includes for large datasets
 */
'unicorn/prefer-set-has': 'error' | 'warn' | 'off';

/**
 * Prefers Set.size over Set conversion to array for length
 */  
'unicorn/prefer-set-size': 'error' | 'warn' | 'off';

Usage Examples:

// ❌ Bad - array includes for large datasets
const allowedIds = [1, 2, 3, 4, 5, /* ... hundreds more */];
if (allowedIds.includes(userId)) {
  // handle allowed user
}

// ✅ Good - Set.has() for better performance
const allowedIds = new Set([1, 2, 3, 4, 5, /* ... hundreds more */]);
if (allowedIds.has(userId)) {
  // handle allowed user
}

// ❌ Bad - converting Set to array for length
const uniqueItems = new Set(items);
const count = [...uniqueItems].length;

// ✅ Good - using Set.size
const uniqueItems = new Set(items);
const count = uniqueItems.size;

Spread and Destructuring Rules

Rules for proper spread operator and destructuring usage.

/**
 * Prefers spread syntax over legacy methods
 */
'unicorn/prefer-spread': 'error' | 'warn' | 'off';

/**
 * Prevents useless spread operations
 */
'unicorn/no-useless-spread': 'error' | 'warn' | 'off';

/**
 * Prevents useless fallback in spread operations
 */
'unicorn/no-useless-fallback-in-spread': 'error' | 'warn' | 'off';

/**
 * Prevents unreadable array destructuring
 */
'unicorn/no-unreadable-array-destructuring': 'error' | 'warn' | 'off';

/**
 * Enforces consistent destructuring patterns
 */
'unicorn/consistent-destructuring': 'error' | 'warn' | 'off';

Usage Examples:

// ❌ Bad - using apply instead of spread
Math.max.apply(Math, numbers);

// ✅ Good - using spread syntax
Math.max(...numbers);

// ❌ Bad - useless spread
const result = [...[1, 2, 3]];

// ✅ Good - direct assignment
const result = [1, 2, 3];

// ❌ Bad - useless fallback in spread
const merged = [...(array || [])];

// ✅ Good - direct spread with proper fallback
const merged = array ? [...array] : [];

// ❌ Bad - unreadable array destructuring
const [, , , , , , , seventhItem] = array;

// ✅ Good - readable alternative
const seventhItem = array[6];

// ❌ Bad - inconsistent property access
function processUser(user) {
  console.log(user.name);
  console.log(user.email);
  console.log(user.role);
}

// ✅ Good - consistent destructuring
function processUser(user) {
  const { name, email, role } = user;
  console.log(name);
  console.log(email);
  console.log(role);
}

Length and Index Rules

Rules for proper length checking and array index handling.

/**
 * Prevents useless length checks
 */
'unicorn/no-useless-length-check': 'error' | 'warn' | 'off';

/**
 * Prefers negative index access patterns
 */
'unicorn/prefer-negative-index': 'error' | 'warn' | 'off';

/**
 * Prevents unnecessary slice end parameter
 */
'unicorn/no-unnecessary-slice-end': 'error' | 'warn' | 'off';

Usage Examples:

// ❌ Bad - useless length check
if (array.length >= 1) {
  // handle non-empty array
}

// ✅ Good - proper length check
if (array.length > 0) {
  // handle non-empty array
}

// ❌ Bad - complex negative indexing
const lastTwo = array.slice(array.length - 2, array.length);

// ✅ Good - simple negative indexing
const lastTwo = array.slice(-2);

// ❌ Bad - unnecessary slice end
const copy = array.slice(0, array.length);

// ✅ Good - omit unnecessary end parameter
const copy = array.slice();

Configuration Examples

Comprehensive Array and Object Rules

export default [
  {
    plugins: {
      unicorn: eslintPluginUnicorn,
    },
    rules: {
      // Array method rules
      'unicorn/no-array-callback-reference': 'error',
      'unicorn/no-array-method-this-argument': 'error',
      'unicorn/require-array-join-separator': 'error',
      
      // Array search and access
      'unicorn/prefer-array-find': 'error',
      'unicorn/prefer-array-some': 'error',
      'unicorn/prefer-array-index-of': 'error',
      'unicorn/prefer-at': 'error',
      
      // Array transformation
      'unicorn/prefer-array-flat': 'error',
      'unicorn/prefer-array-flat-map': 'error',
      'unicorn/no-magic-array-flat-depth': 'error',
      
      // Object operations
      'unicorn/prefer-object-from-entries': 'error',
      'unicorn/no-unused-properties': 'error',
      
      // Set and Map operations
      'unicorn/prefer-set-has': 'error',
      'unicorn/prefer-set-size': 'error',
      
      // Spread and destructuring
      'unicorn/prefer-spread': 'error',
      'unicorn/no-useless-spread': 'error',
      'unicorn/consistent-destructuring': 'error',
    },
  },
];

Performance-Focused Configuration

export default [
  {
    plugins: {
      unicorn: eslintPluginUnicorn,
    },
    rules: {
      // Optimize array operations
      'unicorn/prefer-array-find': ['error', { checkFromLast: true }],
      'unicorn/prefer-set-has': 'error', // Better for large datasets
      'unicorn/prefer-at': ['error', { checkAllIndexAccess: true }],
      
      // Prevent inefficient patterns
      'unicorn/no-array-callback-reference': 'error',
      'unicorn/no-useless-length-check': 'error',
      'unicorn/prefer-spread': 'error',
      
      // Modern array methods
      'unicorn/prefer-array-flat-map': 'error',
      'unicorn/prefer-array-flat': 'error',
    },
  },
];