본문 바로가기
Frontend/TypeScript

타입스크립트의 타입 종류

by Forsaken Developer 2023. 3. 1.
728x90
728x90

타입스크립트의 타입 종류

Primitives

자바스크립트에서 사용하는 기본형(Primitives) 타입으로는 숫자형, 문자열, 부울(Boolean)형이 있다.

만약 ‘age’라는 변수를 만들어 사용자의 나이를 저장한다면, 여기에는 명확히 숫자만 저장해야 한다고 표시하고 싶을 것이다.

let age : number;
age = 20;

변수 이름 뒤에 콜론을 붙이고 그 뒤에 타입을 표시해 해당 변수에 저장할 자료형 지정하면 된다.

마찬가지로 ‘userName’이라는 변수에 문자열 타입을 지정할 수 있다.

let userName: string = "Myname";

타입스크립트에서는 ‘number’와 ‘string’ 표기가 소문자로 시작되는데 ‘Number’ 나 ‘String’으로 쓰게 되면 자바스크립트의 Number 객체와 String 객체를 가리키게 된다.

또한 isInstructor라는 변수에 부울 값을 저장할 수도 있다.

let isInstructor : boolean;
isInstructor = true;

null과 undefined 타입도 있지만 무언가를 null로 지정하는 경우는 잘 없다.

let hobbies : null;

‘hobbies’라는 변수를 만들고 이렇게 null로 지정할 수는 있으나 이후에 다른 값을 할당하려고 하면 오류가 발생한다.

arrays and objects

다음은 배열(array)과 객체(object) 타입이다.

let hobbies: string[];
hobbies = ["coding", "game"];

만약 ‘hobbies’ 변수에 문자열 배열을 저장하고 싶다면 타입을 ‘string’에서 끝내지 않고 뒤에 대괄호를 붙여야 한다.

같은 방식으로 숫자 배열이나 부울 값 배열 같은 것도 만들 수 있다.

person이라는 변수에 이름과 나이 정보를 가진 객체를 저장하려고 한다.

let person;

person = {
  name: "Myname",
  age: 20,
};

기본적으로 어떤 값이든 변수에 저장될 수 있기 때문에 이렇게만 해도 동작할 것이다.

‘any’라는 타입이 있기때문에 기본 타입을 ‘any’로 간주한다.

이렇게 표기하면 타입스크립트에게 이 변수에 저장할 값의 타입에 대해 어떤 값이든 저장될 수 있다고 말해준다.

let person: any;

person = {
  name: "Myname",
  age: 20,
};

명시적으로 지정하는 것도 역시 가능하다.

하지만 이 타입은 예비적으로 사용되는 타입이므로 사용하지 않는 게 좋다.

타입스크립트를 사용하는 주요 목적과 반대되는 개념이고 any 타입을 사용하면 일반적인 자바스크립트와 다를 게 없다.

let person: {
  name: string;
  age: number;
};

person = {
  name: "Myname",
  age: 20,
};

명확하게 객체의 형태를 정의하는 객체 타입을 추가한다.

이렇게 해서 타입스크립트에게 이런 타입의 객체만 해당 변수에 저장될 수 있다고 알려줄 수 있다.

물론 배열 타입과 객체 타입을 합칠 수도 있다.

객체를 여러 개 가진 ‘people’ 배열을 만든다고 하면 다음과 같이 정의 할 수 있다.

let person: {
  name: string;
  age: number;
}[];

person = [
  {
    name: "Myname",
    age: 20,
  },
];

이런 식으로 타입스크립트 기능과 타입을 조합하여 더 발전된 형태로 구현할 수 있다.

function and parameters

함수를 사용할 때 타입을 지정하는 위치가 따로 있다.

add() 함수는 매개변수를 가질 수 있고 매개변수에 타입도 지정할 수 있다.

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

함수에는 입력만 있는 게 아니라 출력도 있기 때문에 함수에서 타입을 사용할 때는 매개변수의 타입뿐만 아니라 반환 값의 타입도 생각해야 한다.

value라는 매개변수로 받고 타입은 any인 출력 함수를 만든다면 다음과 같다.

function printUserInput(value: any) {
  console.log(value);
}

value 매개변수로 값을 받아서 할 일은 콘솔에 출력하는 것뿐이기 때문에 명확한 타입을 지정할 필요는 없다.

이 함수는 return문이 없고 아무것도 반환하지 않는다.

이럴 경우에 갖는 특별한 반환 타입이 바로 ‘void’이고 void는 null 또는 undefined와 비슷하지만 항상 함수와 결합해서 사용한다는 특징이 있다.

만약 이 함수의 반환 값을 받아 작업하려면 undefined 타입으로 값을 받아야 한다.

타입 추론(type inference)

let subject = 'typescript';
subject = 1;

‘subject’라는 변수를 만들어 과목명을 저장한다.

그리고 여기에 숫자를 저장하려고 하면 문자열 타입 변수에는 숫자를 할당할 수 없어 오류가 발생한다.

타입을 정의하지 않았지만 오류가 발생하는데 이는 타입스크립트의 핵심 기능인 타입 추론 때문이다.

기본적으로 타입스크립트는 명시적인 타입 표기가 없어도 가능한 많은 타입을 유추하려고 한다.

이는 우리가 작성할 코드가 줄어든다는 뜻이다.

직접 타입을 지정할 수도 있고 잘못된 것도 아니지만 불필요한 작업이다.

변수를 만들고 바로 초기화하면 타입스크립트는 할당된 값의 자료형을 보고 변수에 저장된 값이 문해당 값의 자료형을 이 변수의 타입으로 여기고 사용한다.

불필요하게 타입을 지정하지 않아도 되기때문에 이렇게 타입 추론 기능을 활용해서 코드를 작성하는 게 권장되는 방식이다.

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

이 함수에는 타입이 추론되는 부분이 있는데 함수에서 반환되는 값이 있고 이를 통해 타입스크립트는 반환 값의 타입을 알게 된다.

함수의 반환 값이 갖는 타입을 통해 함수 타입을 추론한다.

유니온(union) 타입

지금까지 살펴본 상황에선 모든 변수가 타입을 하나만 가지고 있다.

하지만 다양한 타입을 여러 개 저장하는 경우도 있을 것이다.

하나의 변수에 문자열과 숫자, 문자열과 문자열 배열 등 서로 다른 형태의 객체를 동일한 변수에 저장해야 하는 경우는 얼마든지 생길 수 있다.

이런 경우에 한 개 이상의 타입을 지정할 수 있게 해주는 기능으로 유니온(union) 타입이라는 기능이 있다.

유니온 타입 지정은 첫 번째 타입 뒤에 파이프 문자(|)를 넣고 뒤에 다른 타입을 추가한다.

let userName: string | string[];
userName = "Myname";
userName = ["Myname"];

유니온 타입은 타입을 지정한 곳이면 어디든 사용할 수 있고 저장할 타입을 필요한 만큼 추가해서 사용할 수 있다.

유니온 타입은 타입스크립트의 핵심 기능 중 하나로 값과 타입을 좀더 유연하게 정의할 수 있게 해준다.

타입 별칭(Type Alias)

타입스크립트 코드를 작성하다 보면 어느 시점부터는 동일한 타입을 반복해서 정의하는 일이 많아질 것이다.

동일한 타입을 정의해도 문제될 건 없지만 코드 중복을 원치는 않을 것이다.

그래서 직접 기본 타입을 만들어 거기에 복잡한 타입을 정의해 두고 그 타입 별칭을 사용한다.

type 키워드 뒤에 원하는 이름을 붙이면, 그게 새로운 타입의 이름이 된다.

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

let person: Person;
let people: Person[];

이건 타입스크립트에만 존재하는 기능이기 때문에 자바스크립트로 컴파일하면 코드에서 사라지게 될 것이다.

타입 별칭 또한 코드가 좀더 간결해지고 관리하기도 수월해지기 때문에 매우 중요한 기능이다.

제네릭(generics)

마지막으로 소개할 기능은 제네릭(generics) 이다.

기존 배열을 변경하지 않고 호출하기만 해도 배열에 새로운 값을 추가할 수 있는 유틸리티 함수를 정의한다.

이 함수는 배열(array)과 값(value)을 매개변수로 가지고 타입에 상관없이 새로운 배열을 만들기 위해서 array와 value 모두 타입을 any로 지정한다.

function insertItemToBegin(array: any[], value: any) {
  const newArray = [value, ...array];
  return newArray;
}

const numberArray = [1, 2, 3];
const updatedArray = insertItemToBegin(numberArray, 0);

이렇게 하면 updatedArray는 앞에 0이 삽입된 배열이 될 것이다.

문제는 updatedArray에 마우스 커서를 올려보면 추론된 배열의 타입이 any라는 것이다.

타입스크립트는 이 배열에 숫자만 들어있다는 것을 인식하지 못한다.

그렇다고 숫자형으로 타입을 지정할 수도 없는데 문자열 배열에 대해 이 유틸리티 함수를 사용해야 하기 때문이다.

타입스크립트는 배열에 들어있는 게 any 타입의 객체나 any 타입의 값이라고 여긴다.

이 문제를 해결하기 위해 ‘제네릭’이라는 기능을 사용한다.

일반적인 자바스크립트는 지원하지 않는 기능으로 타입스크립트에서만 사용할 수 있다.

제네릭 기능을 사용해서 이 함수를 제네릭 함수로 변환할 수 있다.

함수 이름과 매개변수 목록 사이에 <> 를 추가하고 함수 안에서만 사용할 수 있는 제네릭 타입을 정의한다.

보통 ‘Type’의 ‘T’를 따서 사용하지만 어떤 식별자를 사용해도 상관없다.

이제 이 타입을 함수와 매개변수 목록에서 사용할 수 있다.

function insertItemToBegin<T>(array: T[], value: T) {
  const newArray = [value, ...array];
  return newArray;
}

const numberArray = [1, 2, 3];
let updatedArray = insertItemToBegin(numberArray, 0);
const stringArray = insertItemToBegin(["b", "c", "d"], "a");

이 함수를 호출하면 타입스크립트는 여기 들어온 인수의 정확한 값을 살펴봐야 한다는 것을 알게된다.

어떤 타입이든 사용할 수 있지만, 특정 타입을 사용해 함수를 실행하고 나면 해당 타입으로 고정되어 동작한다.

이 기능은 유연성과 타입 안정성 측면에서 도움이 된다.

728x90
반응형

'Frontend > TypeScript' 카테고리의 다른 글

타입스크립트를 사용하는 이유와 설치 방법  (0) 2023.02.28

댓글