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.
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:
parserOptions.project pointing to your tsconfig.jsonUsage 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'
}
}
]
};// 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
}// 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// 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// 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// 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 errorType-aware linting requires TypeScript compilation and can significantly increase linting time:
// Apply only to specific directories
overrides: [
{
files: ['src/**/*.ts', '!src/**/*.test.ts'],
extends: ['universe/shared/typescript-analysis'],
parserOptions: { project: './tsconfig.json' }
}
]// 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' }
}
]
};// Support for multiple TypeScript configurations
overrides: [
{
files: ['src/**/*.ts'],
parserOptions: { project: './src/tsconfig.json' }
},
{
files: ['tools/**/*.ts'],
parserOptions: { project: './tools/tsconfig.json' }
}
]