
게임을 구현하다 보니
지금이 누구 차례인지, 내가 윷을 던져야 하는 타이밍인지, 윷 말을 선택하는 타이밍인지
사용자가 모를거 같다는 생각이 들었다.
그래서 급하게 추가한 modal인데
dialog을 껐다 켰다 하는 wrapper component로 만들고
내부적인 모양만 갈아끼우면 나중에 종류를 추가할때 좋을거 같아서 구성해봤다
interface GameModalCompoProps {
data:
| TurnStartModalInfo //누군가 차례를 시작했을 때 (나와 다른 사람들에게)
| ChoosePieceModalInfo //윷을 다 던지고 쌓아둔 결과를 사용할 때
| CatchPieceModalInfo //상대방의 말을 잡고 한번 더 던질때
| GameEndModalInfo //
| null;
data가 null이면 dialog을 off하고
null이 아니라면 어떤 타입인지에 따라 child component를 갈아끼울 것이다
dialog에 사용되는 data의 type에 따라 컴포넌트를 갈아끼우려고
typeof나 isntanceof를 사용해봤는데 사용자 정의 타입에는 사용을 못한다고 한다
그러다가 찾은것이 type gard 였다.
function isFish(pet: Fish | Bird): pet is Fish {
return (pet as Fish).swim !== undefined;
}
pet is Fish 이 부분이 type predicates 라는 문법?이다.
사용자 정의 type gard를 만드려면 return type이 type predicates 이면 된다.
isFish가 true를 return하면 pet은 Fish type이라고 주장할 수 있게 된다.
📌 주의!
pet이 정말 Fish type인지 검사하는 것은 개발자가 할 일이므로
제대로 검사하지 않으면 잘못된 타입 검사를 할 수도 있으므로 조심해야한다.
그 중에서 TurnStartModalInfo를 예로 들면
interface TurnStartModalInfo {
nowTurnPlayerNickname: string;
isMyTurn: boolean;
}
현재 차례인 사용자의 닉네임과
나 차례일때와 상대방의 차례일때 text가 다르기 때문에
현재 턴이 나의 차례인지를 property로 사용한다
const instanceOfTurnStartModalInfo = (
object: any
): object is TurnStartModalInfo => {
if (object === null || object === undefined) return false;
return (
"nowTurnPlayerNickname" in object &&
"isMyTurn" in object &&
Object.keys(object).length === 2
);
};
TurnStartModalInfo type의 type gard 함수이다
object 자체가 falsy일수도 있기 때문에 검사해주고
property가 각각 falsy인지랑 property의 개수를 검사해주었다
원하던 구조를 type gard를 이용해 구현해서 만족한다.
다만 급하게 작성한다고 type 검사 구문을 다듬지 않았던거 같다
falsy 검사를 !object로 간단하게 할 수 있는데
왜 null인지 undefined인지 검사하도록 해놨을까...