typescript-eslint은 ESLint에 TypeScript의 타입 정보를 활용한 고급 린팅 규칙 을 추가하는 플러그인입니다.

설치와 설정

BASH
npm install --save-dev eslint @typescript-eslint/parser @typescript-eslint/eslint-plugin

Flat Config (ESLint 9+)

TYPESCRIPT
// eslint.config.mjs
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';

export default tseslint.config(
  eslint.configs.recommended,
  ...tseslint.configs.recommended,
);

타입 인지 린팅 (Type-Aware Linting)

타입 정보를 활용하는 규칙을 사용하려면 추가 설정이 필요합니다.

TYPESCRIPT
// eslint.config.mjs
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';

export default tseslint.config(
  eslint.configs.recommended,
  ...tseslint.configs.recommendedTypeChecked,
  {
    languageOptions: {
      parserOptions: {
        projectService: true,
        tsconfigRootDir: import.meta.dirname,
      },
    },
  },
);

주요 규칙 — 기본

no-unused-vars

TYPESCRIPT
// @typescript-eslint/no-unused-vars
// ❌ 사용하지 않는 변수
const unused = 42; // Error

// ✅ 언더스코어 접두사는 허용 (관례)
const _unused = 42; // OK

// ✅ 구조 분해에서 나머지만 사용
const { used, ...rest } = obj; // rest만 사용해도 OK

no-explicit-any

TYPESCRIPT
// @typescript-eslint/no-explicit-any
// ❌ 명시적 any 사용 금지
function parse(data: any) {} // Error

// ✅ unknown 사용
function parse(data: unknown) {} // OK

consistent-type-imports

TYPESCRIPT
// @typescript-eslint/consistent-type-imports
// ❌ 일반 import로 타입 가져오기
import { User } from './types';

// ✅ 타입 전용 import 명시
import type { User } from './types';

주요 규칙 — 타입 인지

타입 정보를 활용하는 규칙은 tsconfig.json의 타입 정보를 읽어서 동작합니다.

no-floating-promises

TYPESCRIPT
// @typescript-eslint/no-floating-promises
// ❌ Promise를 처리하지 않음
async function fetchData() { /* ... */ }
fetchData(); // Error: Promise가 처리되지 않음

// ✅ await 또는 .then()으로 처리
await fetchData();
// 또는
fetchData().catch(console.error);
// 또는 의도적으로 무시할 때
void fetchData();

공부하다 보니 이 규칙이 실무에서 가장 유용하더라고요. Promise를 처리하지 않으면 에러가 조용히 무시됩니다.

no-misused-promises

TYPESCRIPT
// @typescript-eslint/no-misused-promises
// ❌ async 함수를 boolean 위치에 사용
const isValid = async () => { /* ... */ };
if (isValid()) { /* ... */ } // Error: Promise는 항상 truthy

// ❌ 이벤트 핸들러에 async 함수 전달 (void 반환이어야 함)
// <button onClick={async () => { await save(); }}>저장</button>

await-thenable

TYPESCRIPT
// @typescript-eslint/await-thenable
// ❌ Promise가 아닌 값을 await
const value = 42;
const result = await value; // Error: 42는 thenable이 아님

// ✅ Promise만 await
const result2 = await Promise.resolve(42); // OK

no-unsafe-assignment / no-unsafe-call

TYPESCRIPT
// @typescript-eslint/no-unsafe-assignment
// ❌ any 타입 값 할당
const data: any = getExternalData();
const name = data.user.name; // Error: any 전파

// ✅ unknown으로 받고 타입 좁히기
const data2: unknown = getExternalData();
if (isUser(data2)) {
  const name = data2.name; // OK
}

추천 설정 조합

TYPESCRIPT
// eslint.config.mjs — 실무 추천
import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';

export default tseslint.config(
  eslint.configs.recommended,
  ...tseslint.configs.strictTypeChecked,
  ...tseslint.configs.stylisticTypeChecked,
  {
    languageOptions: {
      parserOptions: {
        projectService: true,
        tsconfigRootDir: import.meta.dirname,
      },
    },
    rules: {
      // 프로젝트에 맞게 조정
      '@typescript-eslint/no-unused-vars': ['error', {
        argsIgnorePattern: '^_',
        varsIgnorePattern: '^_',
      }],
      '@typescript-eslint/consistent-type-imports': 'error',
      '@typescript-eslint/no-floating-promises': 'error',
    },
  },
);

설정 프리셋 비교

프리셋엄격도타입 인지
recommended기본X
recommendedTypeChecked기본O
strict높음X
strictTypeChecked높음O
stylistic코드 스타일X
stylisticTypeChecked코드 스타일O

성능 고려사항

타입 인지 린팅은 타입 체커를 실행 하므로 일반 린팅보다 느립니다.

JSON
// 대규모 프로젝트에서 성능 최적화
{
  "parserOptions": {
    "projectService": true,  // project보다 빠른 새 옵션
    "tsconfigRootDir": "."
  }
}

면접 포인트: "타입 인지 린팅을 쓰면 왜 느려지나요?"라고 물어보면, "ESLint가 AST만 보는 게 아니라 TypeScript 컴파일러의 타입 정보도 읽어야 하기 때문입니다"라고 답하면 됩니다.

정리

  • typescript-eslint은 TypeScript 전용 ESLint 규칙을 제공한다
  • 타입 인지 린팅은 no-floating-promises, await-thenable 등 강력한 규칙을 포함한다
  • strict + TypeChecked 조합이 가장 엄격한 설정이다
  • 타입 인지 린팅은 타입 체커를 실행하므로 성능 비용이 있다
  • projectService 옵션으로 성능을 개선할 수 있다
댓글 로딩 중...