[Typescript] exercise 2

박세진·2023년 3월 8일
0

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

사이트 : TypeScript Exercises

exercise 2

문제 2: Type "Person"이 빠졌다. TS 오류를 수정하기 위해서 해당 Person을 정의하고 persons 배열과 logPerson 함수에 적용하기

interface User {
    name: string;
    age: number;
    occupation: string;
}

interface Admin {
    name: string;
    age: number;
    role: string;
}

export type Person = unknown;

export const persons: User[] = [
    {
        name: 'Max Mustermann',
        age: 25,
        occupation: 'Chimney sweep'
    },
    {
        name: 'Jane Doe',
        age: 32,
        role: 'Administrator'
    },
    {
        name: 'Kate Müller',
        age: 23,
        occupation: 'Astronaut'
    },
    {
        name: 'Bruce Willis',
        age: 64,
        role: 'World saver'
    }
];

export function logPerson(user: User) {
    console.log(` - ${user.name}, ${user.age}`);
}

persons.forEach(logPerson);

문제를 풀다가 막혔을 때 참고할 수 있는 주소 : https://www.typescriptlang.org/docs/handbook/2/types-from-types.html

union type

2개 이상의 다른 타입으로 구성된 type은 union type이다.

type Age = string | number
  • union members에 일치하지 않는 타입이면 에러가 발생한다.
type Age = string | number

let age: Age = 10;

let age1: Age = '15';

let age2: Age = true;
// Error : Type 'boolean' is not assignable to type 'Age'.
  • 모든 union member에 대해 유효한 경우에만 메서드를 사용할 수 있다.
function printId(id: number | string) {
	console.log(id.toUpperCase());
}
// string에서만 사용 가능한 메서드를 사용할 수 없다.
// Error
// Property 'toUpperCase' does not exist on type 'string | number'.
//  Property 'toUpperCase' does not exist on type 'number'.
  • 구체적으로 타입 좁히기를 하면 모든 union member에 유효하지 않아도 메서드를 사용할 수 있다.
function printId(id: number | string) {
    if (typeof id === 'string') {
	console.log(id.toUpperCase());
    }
}

  • union type을 이용해서 exercise 2번 풀기
 interface User {
    name: string;
    age: number;
    occupation: string;
}

interface Admin {
    name: string;
    age: number;
    role: string;
}

export type Person = User | Admin;

export const persons: Person[] = [
    {
        name: 'Max Mustermann',
        age: 25,
        occupation: 'Chimney sweep'
    },
    {
        name: 'Jane Doe',
        age: 32,
        role: 'Administrator'
    },
    {
        name: 'Kate Müller',
        age: 23,
        occupation: 'Astronaut'
    },
    {
        name: 'Bruce Willis',
        age: 64,
        role: 'World saver'
    }
];

export function logPerson(user: Person) {
    console.log(` - ${user.name}, ${user.age}`);
}

persons.forEach(logPerson);
  • 이 문제에서 user에 occupation과 role 속성에 접근하고 싶다면? 타입 좁히기를 하면 모든 union member에 유효하지 않아도 접근할 수 있다. in 연산자를 사용해서 role, occupation 속성에 접근할 수 있도록 했다.
interface User {
    name: string;
    age: number;
    occupation: string;
}

interface Admin {
    name: string;
    age: number;
    role: string;
}

type Person = User | Admin

const persons: Person[] = [
    {
        name: 'Max Mustermann',
        age: 25,
        occupation: 'Chimney sweep'
    },
    {
        name: 'Jane Doe',
        age: 32,
        role: 'Administrator'
    },
    {
        name: 'Kate Müller',
        age: 23,
        occupation: 'Astronaut'
    },
    {
        name: 'Bruce Willis',
        age: 64,
        role: 'World saver'
    }
];

function logPerson (user: Person) {
    if ( "role" in user) {
        console.log(` - ${user.name}, ${user.age}, ${user.role}`);
    } else {
        console.log(` - ${user.name}, ${user.age}, ${user.occupation}`);
    }
}

persons.forEach(logPerson);

2번 문제를 풀다 보니, user에 role과 occupation 속성에는 어떻게 접근 가능할까? 생각하다가, 공식문서에서 타입 좁히기를 보고 적용해서 접근해보았다. union type은 javascript에 있는 or 연산자로 비슷하게 생겼네...ㅎ

profile
경험한 것을 기록

0개의 댓글