ts 4.9 버전 부터 도입된 satisfies
연산자는 타입 검증과 타입 추론을 보다 유연하게 수행할 수 있도록 도와준다. 타입이 기대한 타입을 만족하는지 확인하면서도, 추가적인 속성들을 허용하여 타입 오류를 방지할 수 있다. 예시를 살펴보자.
먼저, 타입과 함수들을 정의한다.
type NumberProcessor = {
process: (value: number) => void;
};
type StringProcessor = {
process: (value: string) => void;
};
// number 타입의 값을 처리하는 함수
const processNumber: NumberProcessor = {
process(value: number) {
console.log(`Processing number: ${value}`);
}
};
// string 타입의 값을 처리하는 함수
const processString: StringProcessor = {
process(value: string) {
console.log(`Processing string: ${value}`);
}
};
이제 satisfies
연산자를 사용하여 타입 검증을 수행한다. 각 객체는 각각의 타입 조건을 만족하지만, 추가적인 속성들을 허용한다.
// number와 string 타입 모두를 처리할 수 있는 객체
const mixedProcessor = {
process(value: number | string) {
if (typeof value === 'number') {
processNumber.process(value);
} else if (typeof value === 'string') {
processString.process(value);
}
}
} satisfies NumberProcessor & StringProcessor;
위의 코드에서 mixedProcessor 객체는 NumberProcessor와 StringProcessor 타입의 조건을 모두 만족한다. process 함수는 number
또는 string
타입의 값을 받아서 각각의 타입에 맞는 처리 함수를 호출한다.
mixedProcessor.process(42); // Output: Processing number: 42
mixedProcessor.process('hello'); // Output: Processing string: hello
이 예제에서는 satisfies 연산자를 사용하여 mixedProcessor 객체가 NumberProcessor와 StringProcessor 타입의 조건을 만족하는지 검증하면서, 추가적인 타입 검사를 수행하지 않아도 된다. 이는 타입 안전성을 유지하면서도, 유연한 코드 작성을 가능하게 한다.
as const
는 ts에서 값이나 객체를 불변성(immutable)으로 만드는 데 사용된다. 이를 통해 변수의 값을 리터럴 타입으로 강제하여 상수처럼 사용할 수 있. as const
는 값이 변경되지 않음을 보장하고, 이를 통해 특정한 변수 또는 값이 명시적인 타입을 지정할 수 있도록 도와준다.
const user = {
name: 'Alice',
age: 25,
role: 'admin'
} as const;
// user의 타입은 user객체의 각 키에 할당된 값으로 좁혀진다.
// {
// readonly name: 'Alice';
// readonly age: 25;
// readonly role: 'admin';
// }
const roles = ['admin', 'user', 'guest'] as const;
// roles의 타입은 각 요소들의 값을 함께 가지고 있는 타입으로 좁혀진다.
// readonly ['admin', 'user', 'guest']
as const와 타입 추론의 차이
기본적으로 ts는 변수의 값을 더 넓은 타입으로 추론하려는 경향이 있다. 예를 들어, 문자열을 할당하면 해당 변수는 일반적인 string
타입으로 추론된다. 하지만 as const
를 사용하면 값이 리터럴 타입으로 추론된다.
const status = 'success'; // status의 타입은 string
const status = 'success' as const; // status의 타입은 'success'
이러한 as const 키워드는 redux와 같은 상태관리 라이브러리에서 액션 타입을 정의할 때 유용하다.
const ActionTypes = {
ADD_TODO: 'ADD_TODO',
REMOVE_TODO: 'REMOVE_TODO'
} as const;
type ActionTypes = typeof ActionTypes[keyof typeof ActionTypes];
이렇게 하면 ActionTypes 객체의 모든 속성이 불변이 되며, 각 속성의 값은 해당 값의 리터럴 타입으로 강제된다. 이는 액션 타입을 정의하고 사용할 때 타입 안전성을 보장한다.