satisfies는 버전4.9에서 처음 소개된 키워드이다.
as는 이미 알고 있었다.
satisfies는 의미로 봐서 as랑 비슷할 것같다.
그럼, satisfies는 정확히 무엇이고 , 두가지 키워드의 차이는 뭘까?
항상 모든 단어의 뜻을 먼저 생각해보자.
만족시키다
란 뜻이다. A satisfies B라고 하면 A의 여러 속성중 B를 만족한다고 보면 된다. 다르게 말하면, B는 A에 포함된다고도 할 수 있을 것 같다.
코드를 보자
type Colors = "red" | "green" | "blue";
type RGB = [red: number, green: number, blue: number, ...rest: string[]]; //맨아래 섹션 ## type element inside array. 에서 추가 설명할것을 미리 알려드림
const palette:Record<Colors, string | RGB> = {
red: [255, 0, 0],
green: "#00ff00",
/**
Object literal may only specify known properties, and 'bleu' does not exist in type 'Record<Colors, string | RGB>'
*/
bleu: [0, 0, 255],
};
/**
Property 'sort' does not exist on type 'string | RGB'.
Property 'sort' does not exist on type 'string'.ts(2339)
*/
palette.blue.sort();
우선 type assertion 이용해 palette의 타입을 설정해주자.
그럼 두 군데서 에러가 난다.
1번은 쉽게 이해가능하다. 근데 2번은?? 왜냐면 bleu의 타입이 string인지 RGB인지 확신을 못하기 때문이다. string일 수 도 있고 RGB일 수 도 있기 때문.
그래서 string일 경우 sort api를 사용할 수 없다고 컴파일 과정에서 타입스크립트가 알려주는 것이다.
이때 satisfies
comes in handy가 된다.
const palette = {
red: [255, 0, 0],
green: "#00ff00",
blue: [0, 0, 255],
} satisfies Record<Colors, string | RGB>
palette.blue.sort();
이번엔 에러가 없다.
이유는 string | RGB 타입을 평가한다음, string | RGB중 palette 안에 할당된 값을 만족시키는 것이 있는지 확인한다. 있다면 그 값을 할당하는 것이다.
inference를 가능하게 한다고 할 수 있으려나?
그리고 만약 bleu라고 오타를 냈다면 오타또한 알려줄 것이다.
이번엔 as를 알아보자.
쉽게 말해 type assertion을 하게 하는 키워드이다. 이름 그 자체의 의미에서도 알 수 있듯이 const john = {name:'john'} as {name:'kyle'}
이라고 한다면 이제부터 john은 kyle이야. 날 믿어!
라며 강제로 고정시켜버리는 것을 의미한다.
근데 이게 문제가 될 수 있다.
정말 확실하게 확신을 가지지 않는다면 사용해선 안된다. 왜냐면 실제와 다른 타입을 assertion하게 될 수 있기 때문.
export interface User {
isActive: boolean;
isVerified: boolean; // ++
id: string;
}
const user = { isActive: true, id: '12-34m2ks' } as User;
function createUserName(user:User) {
if(user.isVerified) {
return user
}
return {...user,name:'haha'}
}
createUserName(user)
이라고 해보자. 그런데 user에는 isVerified
prop이 없다. 그럼에도 함수를 호출했을때 에러가 나지 않는다. 이유는 complie과정에서 as
키워드로 인해 user
를 User
로 인식하기 때문.
type RGB = [red: number, green: number, blue: number, ...rest: string[]];
위의 코드가 잘 이해가지 않았다.
쉽게 말하면, array안에 있는 element를 하나하나 정확하게 명시하기 위함이다.
const rgb:RGB = [10,30,60]
라고 한다면 ,
10이 red / 30이 green / 60이 blue를 가리킨다.
...rest:string[]
은 60뒤에 추가될지도 모르는 element를 의미한다. 그리고 , string만 올 수 있다.
그러나 만약 아래와 같이 코드를 짠다고 하면.
type RGB = [red: number, green: number, blue: number];
const rgb:RGB = [10,30,60,70]
Type '[number, number, number, number]' is not assignable to type 'RGB'.
Source has 4 element(s) but target allows only 3.
라고 에러가 뜰것이다. rgb 배열안에 들어갈 원소의 갯수까지 맞춰주어야 하기 때문.