typescript/no-empty-object-type 제한
동작 방식
{} 타입이 비정의 값이 아닌 모든 값을 허용함으로 인해 혼란을 유발할 수 있으므로, 이 규칙은 {} 타입의 사용을 금지합니다. 이는 필드가 없는 인터페이스와 객체 타입 별칭 모두 포함됩니다.
왜 나쁜가요?
타입스크립트에서 {} 또는 "빈 객체" 타입은 타입스크립트의 구조적 타이핑에 익숙하지 않은 개발자들에게 흔한 혼란의 원인이 됩니다. {}는 0이나 "" 같은 리터럴을 포함하여 비정의 값이 아닌 모든 값을 나타냅니다.
보통 {}를 작성하는 개발자들은 실제로 다음 중 하나를 의미하는 경우가 많습니다:
object: 어떤 객체 값이라도 나타냄unknown: null과 undefined 포함 모든 값을 나타냄
즉, "빈 객체" 타입 {}는 사실상 "정의된 모든 값"을 의미합니다. 배열, 클래스 인스턴스, 함수, 문자열 및 심볼과 같은 원시값을 포함합니다.
이 규칙이 보고하지 않는 사례는 다음과 같습니다:
- 교차 타입 내
{}로 구성된 타입(예: 타입스크립트 내장 타입type NonNullable<T> = T & {}와 같은 형태), 타입 시스템 작업에 유용할 수 있음 - 여러 다른 인터페이스로부터 상속받는 인터페이스
예시
이 규칙에 대해 잘못된 코드 예시:
let anyObject: {};
let anyValue: {};
interface AnyObjectA {}
interface AnyValueA {}
type AnyObjectB = {};
type AnyValueB = {};이 규칙에 대해 올바른 코드 예시:
let anyObject: object;
let anyValue: unknown;
type AnyObjectA = object;
type AnyValueA = unknown;
type AnyObjectB = object;
type AnyValueB = unknown;
let objectWith: { property: boolean };
interface InterfaceWith {
property: boolean;
}
type TypeWith = { property: boolean };구성
이 규칙은 다음 속성을 가진 구성 객체를 수용합니다.
allowInterfaces
type: "never" | "always" | "with-single-extends"
default: "never"
빈 인터페이스를 허용할지 여부.
허용되는 값은 다음과 같습니다:
'always': 필드가 없는 인터페이스를 항상 허용'never'(기본값): 필드가 없는 인터페이스를 절대 허용하지 않음'with-single-extends': 단일 기반 인터페이스로부터extend하는 빈 인터페이스만 허용
{ allowInterfaces: 'with-single-extends' } 설정 시 올바른 코드 예시:
interface Base {
value: boolean;
}
interface Derived extends Base {}allowObjectTypes
type: "never" | "always"
default: "never"
빈 객체 타입 리터럴을 허용할지 여부.
허용되는 값은 다음과 같습니다:
'always': 필드가 없는 객체 타입 리터럴을 항상 허용'never'(기본값): 필드가 없는 객체 타입 리터럴을 절대 허용하지 않음
allowWithName
type: string
구성된 이름을 가진 인터페이스와 객체 타입 별칭을 허용하기 위한 정규 표현식 문자열.
기존 코드 스타일에서 {} 대신 object를 사용하지 않고 빈 타입을 선언하는 패턴이 있는 경우 유용할 수 있습니다.
{ allowWithName: 'Props$' } 설정 시 잘못된 코드 예시:
interface InterfaceValue {}
type TypeValue = {};{ allowWithName: 'Props$' } 설정 시 올바른 코드 예시:
interface InterfaceProps {}
type TypeProps = {};사용 방법
이 규칙을 설정 파일이나 커맨드라인에서 활성화하려면 다음을 사용할 수 있습니다:
{
"rules": {
"typescript/no-empty-object-type": "error"
}
}oxlint --deny typescript/no-empty-object-type