or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

basic-config.mdextension-utilities.mdindex.mdnative-config.mdnode-config.mdtypescript-analysis.mdweb-config.md
tile.json

typescript-analysis.mddocs/

TypeScript Type-Aware Linting

Optional enhanced TypeScript linting configuration that utilizes parsed type information for more sophisticated analysis. Provides advanced type-aware rules that can catch complex type-related issues but requires additional setup and may increase linting time.

Capabilities

TypeScript Analysis Configuration

Advanced TypeScript linting rules that require type information from the TypeScript compiler.

// Traditional ESLint config (.eslintrc.js)
module.exports = {
  extends: [
    'universe', // or universe/native, universe/web, universe/node
    'universe/shared/typescript-analysis'
  ],
  overrides: [
    {
      files: ['*.ts', '*.tsx', '*.d.ts'],
      parserOptions: {
        project: './tsconfig.json'
      }
    }
  ]
};

// Flat Config (ESLint 9+)
const { defineConfig } = require('eslint/config');
const universeConfig = require('eslint-config-universe/flat/default'); // or /native, /web, /node
const typescriptAnalysisConfig = require('eslint-config-universe/flat/shared/typescript-analysis');

module.exports = defineConfig([
  ...universeConfig,
  {
    ...typescriptAnalysisConfig,
    languageOptions: {
      ...typescriptAnalysisConfig.languageOptions,
      parserOptions: {
        project: './tsconfig.json'
      }
    }
  }
]);

Configuration Requirements:

  • Must specify parserOptions.project pointing to your tsconfig.json
  • Extends the base TypeScript configuration with additional type-aware rules
  • Requires TypeScript compiler to be available for type checking
  • Only applies to TypeScript files (*.ts, *.tsx, *.d.ts)

Usage Examples:

// Basic TypeScript project with type-aware linting
// .eslintrc.js
module.exports = {
  extends: [
    'universe',
    'universe/shared/typescript-analysis'
  ],
  overrides: [
    {
      files: ['*.ts', '*.tsx', '*.d.ts'],
      parserOptions: {
        project: './tsconfig.json'
      }
    }
  ]
};

// Multi-package monorepo setup
// .eslintrc.js
module.exports = {
  extends: [
    'universe/node',
    'universe/shared/typescript-analysis'
  ],
  overrides: [
    {
      files: ['packages/*/src/**/*.ts'],
      parserOptions: {
        project: ['packages/*/tsconfig.json']
      }
    }
  ]
};

// React Native project with type analysis
// .eslintrc.js
module.exports = {
  extends: [
    'universe/native',
    'universe/shared/typescript-analysis'
  ],
  overrides: [
    {
      files: ['src/**/*.{ts,tsx}'],
      parserOptions: {
        project: './tsconfig.json'
      }
    }
  ]
};

Type-Aware Rules

Async/Await Safety

// Ensures await is used with Promises
'@typescript-eslint/await-thenable': 'warn'

// Prevents unnecessary awaiting of non-Promise values
'@typescript-eslint/no-unnecessary-type-assertion': 'warn'

// Enforces proper return await usage
'no-return-await': 'off'  // Disabled in favor of TypeScript version
'@typescript-eslint/return-await': ['error', 'always']

Examples:

// ❌ await-thenable violations
await 42;                    // Warning: awaiting non-Promise
await 'string';              // Warning: awaiting non-Promise

// ✅ Correct usage
await Promise.resolve(42);   // OK: awaiting actual Promise
await fetch('/api/data');    // OK: fetch returns Promise

// ❌ return-await violations  
async function bad() {
  return Promise.resolve(42); // Error: should use 'return await'
}

// ✅ Correct usage
async function good() {
  return await Promise.resolve(42); // OK: proper return await
}

Promise Handling

// Ensures Promises are properly handled
'@typescript-eslint/no-floating-promises': 'warn'

// Prevents misuse of Promises in conditions
'@typescript-eslint/no-misused-promises': ['error', { checksVoidReturn: false }]

// Enforces error handling
'@typescript-eslint/only-throw-error': 'warn'

Examples:

// ❌ no-floating-promises violations
fetch('/api/data');          // Warning: Promise not handled
Promise.resolve(42);         // Warning: Promise not handled

// ✅ Correct usage
await fetch('/api/data');    // OK: awaited
fetch('/api/data').catch(console.error); // OK: error handled
void fetch('/api/data');     // OK: explicitly ignored

// ❌ no-misused-promises violations
if (Promise.resolve(true)) { } // Error: Promise in condition

// ✅ Correct usage
if (await Promise.resolve(true)) { } // OK: awaited first

Type Assertions and Checks

// Prevents confusing non-null assertions
'@typescript-eslint/no-confusing-non-null-assertion': 'warn'

// Prevents unnecessary type assertions
'@typescript-eslint/no-unnecessary-type-assertion': 'warn'

// Prevents confusing void expressions
'@typescript-eslint/no-confusing-void-expression': 'warn'

Examples:

// ❌ Confusing non-null assertion
if (!(obj!.prop)) { }        // Warning: confusing negation with !

// ✅ Correct usage  
if (!obj!.prop) { }          // OK: clear intent
if (!(obj?.prop)) { }        // OK: optional chaining

// ❌ Unnecessary type assertion
const num = 42 as number;    // Warning: already number
const str: string = 'hello' as string; // Warning: redundant

// ✅ Correct usage
const num = 42;              // OK: type inferred
const element = document.getElementById('id') as HTMLElement; // OK: needed

Array and Iteration Safety

// Prevents for-in loops on arrays
'@typescript-eslint/no-for-in-array': 'error'

// Enforces proper includes usage
'@typescript-eslint/prefer-includes': 'warn'

// Encourages string methods over indexOf
'@typescript-eslint/prefer-string-starts-ends-with': 'warn'

Examples:

// ❌ no-for-in-array violation
const arr = [1, 2, 3];
for (const item in arr) {    // Error: use for-of for arrays
  console.log(item);
}

// ✅ Correct usage
for (const item of arr) {    // OK: for-of for arrays
  console.log(item);
}

// ❌ prefer-includes violation
if (arr.indexOf(item) !== -1) { } // Warning: use includes

// ✅ Correct usage
if (arr.includes(item)) { }  // OK: more readable

// ❌ prefer-string-starts-ends-with violation  
if (str.indexOf('prefix') === 0) { } // Warning: use startsWith

// ✅ Correct usage
if (str.startsWith('prefix')) { } // OK: clearer intent

Modern TypeScript Features

// Encourages nullish coalescing
'@typescript-eslint/prefer-nullish-coalescing': 'warn'

// Encourages optional chaining
'@typescript-eslint/prefer-optional-chain': 'warn'

// Encourages const assertions
'@typescript-eslint/prefer-as-const': 'warn'

// Encourages readonly for arrays that don't change
'@typescript-eslint/prefer-readonly': 'warn'

// Encourages ts-expect-error over ts-ignore (traditional config only)
'@typescript-eslint/prefer-ts-expect-error': 'warn'

// Additional flat config rules
'@typescript-eslint/ban-ts-comment': 'warn'

Examples:

// ❌ prefer-nullish-coalescing violation
const value = input || 'default'; // Warning: may not handle 0, false correctly

// ✅ Correct usage
const value = input ?? 'default'; // OK: only null/undefined trigger default

// ❌ prefer-optional-chain violation
if (obj && obj.prop && obj.prop.method) { } // Warning: use optional chaining

// ✅ Correct usage  
if (obj?.prop?.method) { } // OK: cleaner optional chaining

// ❌ prefer-as-const violation
const colors = ['red', 'blue'] as string[]; // Warning: use as const

// ✅ Correct usage
const colors = ['red', 'blue'] as const; // OK: preserves literal types

// ❌ prefer-ts-expect-error violation
// @ts-ignore
const result = riskyOperation(); // Warning: use @ts-expect-error

// ✅ Correct usage
// @ts-expect-error Known issue with library types
const result = riskyOperation(); // OK: documents expected error

Performance Considerations

Type-aware linting requires TypeScript compilation and can significantly increase linting time:

  • Small projects: Usually acceptable overhead
  • Large projects: May want to run type-aware rules separately or in CI only
  • Monorepos: Consider selective application to specific packages
  • Development: May want to disable for faster feedback during development

Configuration Tips

Selective Application

// Apply only to specific directories
overrides: [
  {
    files: ['src/**/*.ts', '!src/**/*.test.ts'],
    extends: ['universe/shared/typescript-analysis'],
    parserOptions: { project: './tsconfig.json' }
  }
]

CI-Only Usage

// Separate config for CI with full type checking
// .eslintrc.ci.js
module.exports = {
  extends: ['.eslintrc.js', 'universe/shared/typescript-analysis'],
  overrides: [
    {
      files: ['**/*.{ts,tsx}'],
      parserOptions: { project: './tsconfig.json' }
    }
  ]
};

Multiple TSConfig Support

// Support for multiple TypeScript configurations
overrides: [
  {
    files: ['src/**/*.ts'],
    parserOptions: { project: './src/tsconfig.json' }
  },
  {
    files: ['tools/**/*.ts'],
    parserOptions: { project: './tools/tsconfig.json' }
  }
]