[Typescript] exercise 8

박세진·2023년 3월 22일
0

원티드 타입스크립트 챌린지를 듣고, 추천 받은 공부 방법 중에 exercise를 통해서 1부터 10까지 풀 수 있어야 된다고 해서, exercises를 풀면서 타입스크립트를 학습해보기로 했다.

사이트 : TypeScript Exercises

exercise 8

문제 8: PowerUser는 User와 Admin의 모든 필드(type 제외)를 가져와야 하고, 코드에서 모든 필드를 중복 없이 type 'powerUser'를 가지도록 정의해야 된다.

interface User {
    type: 'user';
    name: string;
    age: number;
    occupation: string;
}

interface Admin {
    type: 'admin';
    name: string;
    age: number;
    role: string;
}

type PowerUser = unknown;

export type Person = User | Admin | PowerUser;

export const persons: Person[] = [
    { type: 'user', name: 'Max Mustermann', age: 25, occupation: 'Chimney sweep' },
    { type: 'admin', name: 'Jane Doe', age: 32, role: 'Administrator' },
    { type: 'user', name: 'Kate Müller', age: 23, occupation: 'Astronaut' },
    { type: 'admin', name: 'Bruce Willis', age: 64, role: 'World saver' },
    {
        type: 'powerUser',
        name: 'Nikki Stone',
        age: 45,
        role: 'Moderator',
        occupation: 'Cat groomer'
    }
];

function isAdmin(person: Person): person is Admin {
    return person.type === 'admin';
}

function isUser(person: Person): person is User {
    return person.type === 'user';
}

function isPowerUser(person: Person): person is PowerUser {
    return person.type === 'powerUser';
}

export function logPerson(person: Person) {
    let additionalInformation: string = '';
    if (isAdmin(person)) {
        additionalInformation = person.role;
    }
    if (isUser(person)) {
        additionalInformation = person.occupation;
    }
    if (isPowerUser(person)) {
        additionalInformation = `${person.role}, ${person.occupation}`;
    }
    console.log(`${person.name}, ${person.age}, ${additionalInformation}`);
}

console.log('Admins:');
persons.filter(isAdmin).forEach(logPerson);

console.log();

console.log('Users:');
persons.filter(isUser).forEach(logPerson);

console.log();

console.log('Power users:');
persons.filter(isPowerUser).forEach(logPerson);

extending

User와 Admin의 속성을 다 가져야 되는 PowerUser를 만들기 위해서 extending 하고, type: 'powerUser' 속성을 추가해줘야 함

interface와 type alias의 extending 방법은 다르다.

문제에서는 type alias를 이용해 PowerUser를 선언했기 때문에 type alias를 확장해보았다.

type alias extends

type alias는 & intersections를 통해서 확장시킬 수 있다.

처음에는 이런식으로 작성을 해줬으나, type PowerUser = never 타입이 나오는 것을 확인하였다.

type PowerUser = User & Admin & {
    type: 'powerUser'
}

type 속성이 겹치면서 생기는 문제라고 생각하여 Omit<Type, Keys>을 이용해서 User와 Admin에 type 속성을 제외하고 type을 생성하도록 하였다.

type PowerUser = Omit<User, 'type'> & Omit<Admin, 'type'> & {
    type: 'powerUser'
}

inteface extends

interface는 확장시킬 때 extends 키워드를 사용하여 확장한다. interface NewInterface extends BaseInterface { ... }

interface를 이용해서도 확장해보았다.

interface PowerUser extends Omit<User, 'type'>, Omit<Admin, 'type'> {
    type: 'powerUser'
}

참고
interface와 type alias의 차이점

이 문제 풀려고... 정말 머리싸맸다...
extends 확장 개념은 알고 있었지만, 언제 사용해야 되는지를 잘 모르니... 이렇게 오래 걸리지...ㅠ_ㅠ

profile
경험한 것을 기록

0개의 댓글