[Typescript] 타입스크립트의 타입 선언

타입스크립트란?

타입스크립트 = 자바스크립트 + 타입시스템

- 정적 타입 시스템을 가지고있는 언어

프로그램이 실행되기 전 컴파일타임에 모든 변수와 표현식의 타입을 확인하고 고정하는 방식

이를 이용해 프로그램의 많은 오류를 미리 발견할 수 있음

 

정적 타입 시스템의 장점

1. 오류를 미리 발견할 수 있음

- 실행하기 전 오류를 찾기 때문에 프로그램이 더 안정적으로 작동할 수 있음

 

2. 안정성

- 잘못된 타입의 데이터를 사용하는 실수를 줄일 수 있음

 

 

JS와의 차이

import React from 'react';

const App: React.FC = () => {
  return (
    <div>
      <h1>Hello, World!</h1>
      <p>This is a simple React component.</p>
    </div>
  );
};

export default App;

선언 부분만 조금 다를 뿐이다~~

 

 

타입 선언하기

사용하고자하는 변수에 :를 붙여서 어떤 타입인지 명시해주면 된다.

// 문자열
let color: string = 'red';

// 배열
let fruits: string[] = ['apple', 'banana', 'mango'];
let mixArray: (string | number)[] = ['apple', 1, 2, 'mango'];

// 객체
interface IUser {
  name: string;
  age: number;
  isValid: boolean;
}

let userArr: IUser[] = [
  {
    name: 'neo',
    age: 10,
    isValid: true,
  },
  {
    name: 'lewis',
    age: 64,
    isValid: false
  }
]

 

interface, type

커스텀 타입을 표현하기위해 사용할 수 있는 키워드

두가지 다 마찬가지로 타입은 파스칼 케이스로 선언하는 것이 컨벤션이다

type User = {
  name: string;
  age: number;
  isValid: boolean;
}

let user: User = {
  name: 'neo',
  age: 10,
  isValid: true,
}

 

null, undefined

초기값이 nulll, undefined 였다가 다른 타입의 값이 들어오게 되는 경우가 있다. 이럴 때 활용!

let stringOrNull: string | null = null;
let numberOfUndefined: number | undefined = undefined;

 

 

any

아무거나 들어갈 수 있다.

 

void

아래 함수는 반환값이 없는(void) 함수다. 이럴 때 활용!

function coding(msg: string): void {
  console.log(`Happy ${msg}`);
}

 

 

union

여러 타입이 동시에 가능할 때 사용할 수 있다.

let union: (string | number);

union = 'Hello world';  // 가능
union = 8;  // 가능
union = false;  // 불가

 

 

intersection

두개 이상의 타입을 조합하여 하나의 타입으로 합치는 방식

아래는 User라는 타입과 Validation이라는 타입을 합친 예시

interface IUser {
  name: string,
  age: number
}

interface IValidation {
  isValid: boolean
}

// IUser와 IValidation의 모든 조건이 만족해야함
const testCase2: IUser & IValidation {
  name: 'jisu',
  age: 30,
  isValid: true
}

 

 

함수

let myFunc: (arg1: number, agr2: number) => number;
myFunc = (x, y) => x + y;

let noneFunc: () => void;
noneFunc = function () {
  console.log("Hi");
};

 

 

더 많은 타입들

읽기 전용 readonly

선언 후 수정이 불가한 값을 선언할 때 사용할 수 있다.

let arrA: readonly number[] = [1, 2, 3, 4];
let arrB: ReadonlyArray<number> = [2, 4, 5, 6];

arrA.push(9);  // 에러발생

 

튜플 Tuple

배열인데, 어떤 인덱스에 어떤 타입의 값이 들어와야하는지 정해져있음

let tuple: [string, number];

tuple = ['a', 1];
tuple = [1, 'a'];  // 에러

 

 

열거형 enum

enum Week {
  Sun,
  Mon,
  Tue,
  Wed,
  Thu,
  Fri,
  Sat
}

enum Color {
  Red = 'red',
  Green = 'green',
  Blue = 'blue'
}

 

 

객체 object

object는 객체 뿐만 아니라 배열, 함수 등 다양한 타입을 포함하고 있는 타입이다.

let obj: object = {};
let arr: object = [];
let func: object = () => void;
let date: object = new Date();

 

 

unknown

타입스크립트의 모든 타입의 최상위 타입, 전체집합

 

Never

타입 위계의 최하위타입, 공집합

어떤 타입도 Never에 포함되지 않음

 

function error(message: string): never {
  throw new Error(message);
}

const never: [] = [];
never.push(3);  // 에러

 

 

interface와 type의 차이점

확장성 (Extensibility)

interface는 한번 선언한 이후 뒤에서 다시 선언하는 경우, 확장으로 처리된다

interface User {
  name: string;
}

interface User {
  age: number;
}

// name 혹은 age 중 하나라도 빠트리면 에러
let user: User = {
  name: 'kim',
  age: 20
};

 

type은 중복된 선언 자체가 에러!

type User = { name: string }
type User = { age: number }  // 에러

 

- 따라서 동일한 타입에 새로운 속성을 추가해야하는 경우 인터페이스가 유리

- 객체 형태 뿐만 아니라 유니온, 튜플, 매핑된 타입 등 복잡한 타입 표현에는 타입이 더 유리

type A = B | C;

 

 

구조적 타입

타입스크립트의 타입 시스템은 구조적 타입이다. 구조적 타입 시스템에서는 값의 형태와 구조에 따라 타입이 결정된다.

따라서 다르게 선언한 타입이라도, 그 구조와 값이 같다면 같은 타입으로 간주한다.

 

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

let p1: Person = { name: "alice", age: 25 };
let p2 = { name: 'bob', age: 30 };

p1 = p2;  // 가능, p2가 Person과 동일한 구조를 가졌기 때문

 

'TypeScript' 카테고리의 다른 글

[TypeScript] 제네릭과 유틸리티 타입  (0) 2024.09.24
[TypeScript] 타입 어노테이션과 추론  (0) 2024.09.24