타입스크립트 4.9 버전에 안전한 업캐스팅을 지원하는 satisfies
연산자를 공개했다. satisfies
연산자를 활용하면 타입을 변경하지 않고도 변수에 제약 조건(constraint)을 적용할 수 있다. 즉, 객체 프로퍼티에 제약 조건을 적용하면서 각 프로퍼티의 타입을 올바르게 추론할 수 있다.
<aside> 💡 용어 설명
아래 참가자 정보를 나타내는 attendee
객체가 있다. 객체를 선언하면 타입스크립트는 객체의 각 프로퍼티 타입을 자동으로 추론한다.
그래서 attendee.age
(number
타입으로 추론)에 숫자를 더하거나 attendee.name
(string
타입으로 추론)에 toUpperCase
같은 메서드를 사용할 수 있다. 하지만 attendee
객체가 어떤 프로퍼티로 구성돼 있는지 구체적으로 명시하지 않아서(제약 조건 없음) posittion
같은 오타가 생겨도 에러가 발생하지 않는다.
// attendee: { name: string; age: number; posittion: string; }
const attendee = {
name: 'Smith',
age: 30,
posittion: 'Engineer' // 오타
};
const plusAge = attendee.age + 10; // OK (number 타입으로 추론)
const nameToUpperCase = attendee.name.toUpperCase(); // OK (string 타입으로 추론)
타입 어노테이션(타입 표기)을 사용하면 위 같은 오타를 사전에 방지할 수 있다. 하지만 객체의 각 프로퍼티가 어떤 타입을 가지는지에 대한 정보를 잃게 된다. 결국 attendee
객체의 모든 프로퍼티는 string | number
유니온 타입을 갖게 된다.
type Attendee = 'name' | 'age' | 'position';
const attendee: Record<Attendee, string | number> = {
name: 'Smith',
age: 30,
posittion: 'Engineer' // Error! 오타 감지
};
const plusAge = attendee.age + 10; // Error! ts(2365)
const nameToUpperCase = attendee.name.toUpperCase(); // Error! ts(2339)
때문에 attendee.age
에 10을 더하면 string | number
타입에 +
연산자를 사용할 수 없다고 나온다. 마찬가지로 attendee.name
에 toUpperCase
를 사용하면 string | number
타입에 toUpperCase
속성이 없다는 에러가 발생한다.
위 같은 문제는 satisfies
연산자를 사용하면 해결할 수 있다. 그럼 attendee
객체 프로퍼티를 Attendee
타입으로 제한하면서(제약 조건 적용), 각 프로퍼티의 타입을 올바르게 추론할 수 있다.
type Attendee = 'name' | 'age' | 'position';
const attendee = {
name: 'Smith',
age: 30,
posittion: 'Engineer', // Error! 오타 감지
} satisfies Record<Attendee, string | number>;
const plusAge = attendee.age + 10; // OK (number 타입으로 추론)
const nameToUpperCase = attendee.name.toUpperCase(); // OK (string 타입으로 추론)
unknown
키워드를 사용했을 때도 프로퍼티 타입을 올바르게 추론한다. satisfies
연산자를 사용하지 않으면 각 프로퍼티 값을 사용할 때마다 타입 단언/가드 작업을 해줘야 한다.
type Attendee = 'name' | 'age' | 'position';
const attendee = {
name: 'Smith',
age: 30,
posittion: 'Engineer', // Error! 오타 캐치
} satisfies Record<Attendee, unknown>;
const plusAge = attendee.age + 10; // OK
const nameToUpperCase = attendee.name.toUpperCase(); // OK