코드스테이츠-부트캠프 [TypeScript] 기초(4)

김희목·2024년 4월 1일
0

코드스테이츠

목록 보기
54/56
post-custom-banner

TypeScript의 타입 별칭(Type Aliases)

타입 별칭(Type Aliases)은 타입의 새로운 이름을 만드는 것입니다. 이는 새로운 이름으로 기존의 타입을 참조하는 것을 의미합니다. 타입 별칭을 이용하여 타입의 새로운 이름을 만들 때 키워드 type을 사용하여 작성합니다. 간단한 예시를 보겠습니다.

type MyString = string;

let str1: string = 'hello!';

// string 타입처럼 사용할 수 있습니다.
let str2: MyString = 'hello world!';

원래 string이라는 타입이 존재하고 있었습니다. 이에 myString이라는 새로운 이름을 부여했습니다. 여기서 myString과 string은 동일한 의미를 갖게 됩니다. 즉, 타입을 정의할 수 있는 모든 곳에는 타입 별칭을 쓸 수 있습니다.

이런 방식으로 타입 별칭을 사용하면 코드를 더 간결하고 가독성 좋게 만들 수 있습니다. 또한 복잡한 타입을 간략하게 표현하고, 타입 정의를 재사용하는 등 가독성을 높일 수 있습니다. 아래의 예시를 보겠습니다.

type Person = {
  id: number;
  name: string;
  email: string;
}

//Commentary 인터페이스에서 Person 타입을 참조하고 있습니다.
interface Commentary {
  id: number;
  content: string;
  user: Person;
}

//객체에서 Commentary 인터페이스를 참조하고 있습니다.
let comment1: Commentary = {
    id: 1,
    content: "뭐예요?",
    user: {
        id: 1,
        name: "김코딩",
        email: "kimcoding@codestates.com",
    },
}

//Commentary 인터페이스 내부에 content 프로퍼티가 존재하기 때문에 
//content 프로퍼티를 작성하지 않으면 컴파일 에러가 납니다.
let kimcoding: Commentary = {
    id: 1,
    user: {
        id: 1,
        name: "김코딩",
        email: "kimcoding@codestates.com",
    },
};

//Person 타입 내부에 isDeveloper 프로퍼티가 존재하지 않기 때문에 
//isDeveloper 프로퍼티를 작성할 시 컴파일 에러가 납니다.
let kimcoding: Commentary = {
    id: 1,
    content: "뭐예요?",
    user: {
        id: 1,
        name: "김코딩",
        email: "kimcoding@codestates.com",
        isDeveloper: true,
    },
};

이처럼 인터페이스나 다른 변수를 정의할 때 타입 별칭으로 정의한 타입을 참조하게 됨으로써 코드를 더 간결하고 가독성 좋게 만들 수 있습니다. 타입 별칭으로 만들어진 타입을 참조할 시에는 인터페이스와 마찬가지로 내부에 정의된 프로퍼티를 전부 참조해야만 합니다. 또한 타입 별칭으로 만들어진 타입 내부에 정의된 프로퍼티 외에 다른 프로퍼티를 더 작성하게 되면 그 또한 컴파일 에러가 납니다.


인터페이스 vs 타입 별칭

타입 별칭 또한 인터페이스와 같은 특징이 있기 때문에, 인터페이스의 역할을 타입 별칭이 수행할 수도 있습니다. 그러나 인터페이스와 타입 별칭에는 미묘한 차이점이 있습니다.

type Person = {
    name: string;
    age: number;
}

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

let kimcoding: Person = {
    name: '김코딩',
    age: 30,
}

let coding: User = {
    name: '김코딩',
    age: 30,
}

위와 같이 코드들이 작성되어 있습니다. 작성하는 동안 정의한 타입이나 인터페이스 내부에 어떤 프로퍼티가 들어가 있는지 기억이 나지 않을 경우가 있습니다. 그래서 kimcoding이 참조하고 있는 Person 타입과, coding이 참조하고 있는 User 인터페이스에 각기 마우스를 올려놓아 보았습니다.

VSCode로 작성 시, kimcoding 객체가 참조하고 있는 Person에 마우스를 올리면 Person 내부에 어떤 프로퍼티들이 정의되어 있는지 보입니다. 그러나 coding 객체가 참조하고 있는 User에 마우스를 올리면 User 내부에 어떤 프로퍼티들이 정의되어 있는지 보이지 않습니다.

따라서 타입 별칭으로 정의한 타입으로 작성할 시에는 조금 더 편하게 코드를 작성할 수 있게 됩니다.

또 이러한 차이점이 있습니다.

type Person = {
    name: string;
    age: number;
}

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

//에러가 발생합니다.
type Students extends Person {
    className: string;  
}

//정상적으로 동작합니다.
interface Students extends User {
	 className: string;   
}

//정상적으로 동작합니다.
interface Students extends Person {
    className: string;  
}

타입 별칭은 말 그대로 타입에 새로운 이름을 부여하는 것에서 그치기 때문에 확장이 되지 않습니다. 그러나 인터페이스는 확장이 가능합니다. 인터페이스는 기존의 인터페이스 및 타입 별칭으로 만들어진 타입 둘 다 상속할 수 있기 때문에, 유연한 코드 작성을 위해서는 인터페이스로 만들어서 필요할 때마다 확장할 수 있습니다.


JavaScript를 TypeScript로 포팅 하기 - 타입 별칭

/* 코드를 작성한 뒤 
1. tsc src/index.ts
2. node src/index.js
순으로 터미널에 입력하여 결과를 확인해 주세요.
*/

// Todo 타입 정의
interface Todo {
  id: number;
  title: string;
  isDone: boolean;
}

// Todo 타입을 사용해 객체를 정의합니다.
const show: Todo = {
  id: 1,
  title: 'Example todo',
  isDone: true,
};

// Todo 타입을 사용한 객체를 출력하는 함수
function getTodo(todo: Todo): void {
  console.log(todo);
}

// 함수 호출
getTodo(show);


TypeScript의 타입 추론(Type Inference)

TypeScript는 정적타입을 지원하는 프로그래밍 언어입니다. 정적타입 시스템을 사용하면 코드의 안정성을 높이고 디버깅을 용이하게 할 수 있습니다.

TypeScript는 타입 추론(Type Inference)이라는 기능을 통해 코드 작성을 도와줍니다.


타입 추론(Type Inference)의 기본

타입 추론(Type Inference)은 변수나 함수의 타입을 선언하지 않아도 TypeScript가 자동으로 유추하는 기능입니다. 예를 들어, 다음과 같은 코드를 살펴보겠습니다.

let isNumber = 123;

이 코드에서는 변수 isNumber를 선언하고, 숫자 123을 할당했습니다. 이 경우, 타입스크립트는 isNumber의 타입을 자동으로 숫자(Number)로 추론합니다.


최적 공통 타입 (Best common type)

TypeScript는 여러 표현식에서 타입 추론이 발생할 때, 해당 표현식의 타입을 사용하여 "최적 공통 타입"을 계산합니다. 아래와 같은 코드가 있다고 가정해 보겠습니다.

let x = [0, 1, null];

위 예제의 x 타입을 추론하려면 각 배열 요소의 타입을 고려해야 합니다. 여기서 배열의 타입으로 고를 수 있는 두 가지 후보가 있습니다: number와 null입니다. 최적 공통 타입 알고리즘은 각 후보의 타입을 고려하여, 모든 후보의 타입을 포함할 수 있는 타입을 선택합니다.


문맥상의 타이핑(Contextual Typing)

타입스크립트에서 타입을 추론하는 또 하나의 방식은 바로 문맥상으로 타입을 결정하는 것입니다. 이 문맥상의 타이핑(타입 결정)은 코드의 위치(문맥)를 기준으로 일어납니다. 다음과 같은 함수를 살펴보겠습니다.

function add(a, b) {
  return a + b;
}

add 함수는 두 개의 매개변수를 받아 더한 값을 반환합니다. 하지만 매개변수의 타입이 명시되어 있지 않습니다. 이 경우, 타입스크립트는 매개변수 a와 b의 타입을 자동으로 추론했습니다. 만약 매개변수 a와 b가 모두 숫자(Number) 타입이라면, add 함수의 반환 값도 숫자(Number) 타입으로 추론됩니다.


타입 추론의 장점

이런 타입 추론에는 몇 가지 장점이 있습니다.

  1. 코드의 가독성 향상: 타입 추론을 사용하면 코드의 가독성이 향상됩니다. 명시적으로 타입을 지정하지 않아도 코드에서 변수의 타입을 알 수 있기 때문입니다.

  2. 개발 생산성 향상: 타입 추론을 사용하면 코드 작성 시간을 단축할 수 있습니다. 명시적으로 타입을 지정하지 않아도 TypeScript가 자동으로 타입을 추론하기 때문입니다.

  3. 오류 발견 용이성: 타입 추론을 사용하면 코드의 오류를 발견하는 것이 쉬워집니다. TypeScript는 변수나 함수의 타입을 추론하여 타입 검사를 수행하기 때문입니다.


타입 추론의 단점

그러나 타입 추론이 늘 좋은 것만은 아닙니다. 몇 가지 단점도 있습니다.

  1. 타입 추론이 잘못될 경우 코드 오류 발생: 타입 추론은 TypeScript가 자동으로 수행하는 것이기 때문에, 추론이 잘못될 경우 코드 오류가 발생할 수 있습니다.

  2. 명시적인 타입 지정이 필요한 경우가 있음: 타입 추론만으로는 부족한 경우가 있습니다. 특히, 복잡한 함수나 객체의 경우에는 명시적인 타입 지정이 필요할 수 있습니다.

따라서, 타입 추론은 TypeScript의 장점 중 하나이지만, 때에 따라 명시적인 타입 지정이 필요한 경우도 있습니다.

post-custom-banner

0개의 댓글