타입스크립트 사용법과 기본 타입 정리

2025. 5. 26. 15:48·React

자바스크립트는

변수의 타입을 미리 지정하지 않아도 자유롭게 사용할 수 있는 동적 언어

개발 속도를 빠르게 해주는 장점도 있지만,
반대로 타입 관련 버그가 런타임에서야 발견될 수 있는 단점이 존재

 

=> 이런 문제를 해결하고자 나온 것이 바로  타입스크립트(TypeScript)


1. 타입스크립트

  • 정적 타입 시스템을 통해 코드를 실행하기 전에 변수의 타입을 정적으로 결정
  • 물론 모든 변수에 타입을 지정해야 해서 유연하지 못하다는 단점

타입스크립트는 점진적 타입 시스템을 채택
모든 곳에 타입을 강제로 지정하지 않아도, 타입스크립트가 자동으로 타입을 추론

=> 이를 통해 유연함과 타입 안정성을 모두 가져갈 수 있게 된다.

 

브라우저나 Node.js가 .ts 파일을 직접 실행할 수 없음
→ 반드시 자바스크립트로 컴파일 후 실행해야 함

2. 타입스크립트 사용법

 

2-1 프로젝트 초기화

npm init

 

 

2-2 타입스크립트와 타입 정의 설치

npm i typescript
npm i @types/node
 

2-3  타입스크립트 컴파일

tsc src/index.ts

=> 위 명령어를 실행하면 .ts 파일이 .js로 컴파일

 

2-4   ts-node 사용 (ts 파일을 바로 실행 가능)

npm i -g ts-node
ts-node src/index.ts
=> 현재는 사용이 안됌

npm i -g tsx
=>해당 방식으로 실행해야함

3. 타입스크립트 컴파일러 설정

타입스크립트는 매우 다양한 컴파일 옵션을 제공

아래 명령어로 기본 설정 파일을 생성할 수 있다!!!!

tsc --init

 

3-1. 컴파일 범위 설정

 

기존에는 개별 파일을 하나하나 컴파일해야 했으나!
=> include 옵션을 사용하면 여러 파일을 한 번에 컴파일 가능

{ "include": ["src"] }
 
 

3-2 자주 사용하는 컴파일러 옵션 

{
  "compilerOptions": {
    "target": "ESNext",        // 어떤 버전의 JS로 변환할지
    "module": "ESNext",        // 사용할 모듈 시스템 (예: ESNext, CommonJS)
    "outDir": "dist",          // 결과물이 생성될 디렉토리
    "strict": false            // 타입을 얼마나 엄격하게 검사할지
  },
  "include": [
    "src"
  ]
}

 


4. 스코프와 모듈

자바스크립트에서는 각각의 파일이 모듈로 간주!!
타입스크립트에서는 별도로 설정하지 않으면 각 파일이 전역 스코프로 인식

즉, 타입스크립트는 서로 다른 파일에서 동일한 변수명을 사용하면 에러가 발생할 수 있다!!!

 

- 해결 방법

 

4-1. export 사용

const a = 1;
export {}; // 이렇게 명시하면 해당 파일은 모듈로 인식됨

 

4-2. moduleDetection 옵션

{
  "compilerOptions": {
    "moduleDetection": "force"
  }
}

 

=> 이 옵션을 설정하고 컴파일하면, 아래와 같이 export {}가 자동으로 추가

const a = 1;
export {}; // 자동 추가됨

5. ES Module 관련 설정

다음과 같이 설정: "moduleDetection": "force"       // 모듈로 인식하도록 강제

 

5-1 tsconfig.json

{
  "compilerOptions": {
    "target": "ESNext",              // 최신 JS 문법 사용
    "module": "ESNext",              // ES 모듈 사용
    "outDir": "dist",                // 컴파일된 파일이 생성될 디렉터리
    "strict": false,                 // 엄격한 타입 검사 비활성화
    "moduleDetection": "force"       // 모듈로 인식하도록 강제
  },
  "include": [
    "src"
  ]
}
 
=>  tsx src/index.ts를 실행했을 때 오류가 발생

=> 이는 package.json에 "type": "module" 설정이 없기 때문!!

 

5-2 package.json

{
  "type": "module"
}

 

5-3 그런데도 또 오류 발생?

 

이는 ts-node가 기본적으로 CommonJS 환경에서 실행되기 때문
해결하려면 tsconfig.json에 아래 설정을 추가

{
  "ts-node": {
    "esm": true
  }
}

=> ES 모듈을 제대로 인식하도록 하려면, tsconfig.json 추가 설정

 


6. 타입 검사 생략 옵션

타입스크립트는 기본적으로 외부 라이브러리의 타입도 검사!!
하지만 아래 옵션을 사용하면 이러한 타입 검사 과정을 생략할 수 있어 컴파일 속도가 향상

{
  "compilerOptions": {
    "skipLibCheck": true
  }
}

 

=>타입 검사 속도를 높이고, 외부 라이브러리에서 발생하는 타입 오류를 무시

 


타입스크립트를 처음 접할 때 꼭 알아야 할

기본 타입 개념부터 객체, 튜플, enum, 타입 호환성 정리

7. 타입스크립트 타입

7-1. 기본 타입 (Primitive Types)

타입스크립트에서 기본 타입은 원시 타입으로 불리며, 하나의 값만 저장할 수 있는 타입
  • number
  • string
  • boolean
  • null
  • undefined

 Number

let num1: number = 123;
let num2: number = -123;
let num3: number = 0.123;
let num4: number = -0.123;
let num5: number = Infinity;
let num6: number = -Infinity;
let num7: number = NaN;

num1.toFixed();
// num1 = "hello"; //  오류 발생 //문자에만 쓰는거 안돼!

String

let str1: string = "hello";
let str2: string = "hello";
let str3: string = `hello`;
let str4: string = `hello ${num1}`;

Boolean

let bool1: boolean = true;
let bool2: boolean = false;

Null & Undefined

let null1: null = null;
let unde1: undefined = undefined;

 

기본적으로 number, string 같은 타입에 null을 넣을 수 없지만!
필요하다면 tsconfig.json 설정을 추가해서사용가능!!!

{
  "compilerOptions": {
    "strictNullChecks": false
  }
}

=> 설정 안하면 strict에 따라서 달라짐

 

7-2. 리터럴 타입 (Literal Types)

let numA: 10 = 10;
let strA: "hello" = "hello";
let boolA: true = true;
리터럴의 의미 = 값
타입에 값을 집어 넣으면 다른 값이 안됌

 

7-3. 배열 (Array)

두가지 방식 [] <>제네릭방식

단일 타입 배열

let numArr: number[] = [1, 2, 3];
let strArr: string[] = ["hello", "img"];
let boolArr: Array<boolean> = [true, false];

복합 타입 배열

let multiArr: (number | string)[] = [1, "hello"];

=> 점진적 타입 타입 추론!!! 마우스로 올려보면 타입이 나옴

다차원 배열

let doubleArr: number[][] = [
  [1, 2, 3],
  [4, 5],
];

 

7-4. 튜플 (Tuple)

:  타입스크립트만 있는 타입 / 길이가 타입이 고정된 배열

let tup1: [number, number] = [1, 2];
let tup2: [number, string, boolean] = [1, "2", true];

 

배열 메소드를 사용해도 오류가 나지 않음!! => 주의 필요

tup1.push(1); //타입 안정성 주의 필요!!!
tup1.pop();
tup1.pop();
tup1.pop();
tup1.pop();

튜블도 기본 배열로 인식을 해서 이렇게 사용해서 오류가 안남
그러나 이러면 내가 정한 길이가 문제가 생길 수 있으므로 주의 필요

배열 사용 시 index 위치에 따라 순서가 정해져 있고 중요할 때 값을 안 넣게 방지

 const users: [string, number][] = [
   ["이정환", 1],
   ["아무", 2],
   ["김씨", 3],
   ["박씨", 4],
   [5, "호씨씨"],
 ];

 

7-5. 객체 (Object)

 let user: object = {
     id: 1,
     name : "이정환"
 }

user.id;=> 오류
타입스크립트의 object는 객체인데 잘 모르겠네? 하는 느낌
object를 사용하는게 아니라 객체리터럴을 사용해야함

 

객체 리터럴 타입 

let dog: {
  name: string;
  color: string;
} = {
  name: "돌돌아",
  color: "brown",
};

user.id;

 

: 구조를 기준으로 타입을 지정
=> 구조적 타입 시스템
=> property Based 타입시스템
=> 자바나 c는 명목전 타입 시스템

선택적 프로퍼티

: ?타입이 있어도 되고 없어도 된다

let user: {
  id?: number;
  name: string;
} = {
  id: 1,
  name: "이정환",
};

user = {
    name: "홍길동동"
}

=> 선택적 프로퍼터 optional 프로퍼티

읽기 전용 프로퍼티

: 프로퍼티의 값을 바꾸는 것을 막아줌 readonly

let config: {
  readonly apikey: string;
} = {
  apikey: "MY API KEY"
};

config.apikey = "hacked"; // 오류

 

7-6. 타입 별칭 (Type Alias)

: 타입을 변수처럼 사용 할 수 있는 타입 별칭

type User = {
  id: number;
  name: string;
  nickname: string;
  birth: string;
  bio: string;
  location: string;
};

let user: User = {
  id: 1,
  name: "홍길동",
  nickname: "winterlood",
  birth: "1997.01.07",
  bio: "안녕하세요",
  location: "부천시",
};
조심 할점!! 같은 스코프내 중복된 이름은 안돼~
js에서 타입별칭은 사라짐

 

7-7. 인덱스 시그니처

 type CountryCodes = {
   Korea: string;
   UnitedState: string;
   UnitedKingdom: string;
 };

=> 나라가 여러개면 이거 다 쓰라고??안돼!!

 

key value 의 규칙으로 타입을 정함!!!
type CountryCodes = {
    [key: string]: string;
};

 

let countryCodes: CountryCodes = {
  Korea: "ko",
  UnitedState: "us",
  UnitedKingdom: "uk",
};

 

인덱스 시그니처는 규칙을 위반만 안하면 괜찮아서

=> 빈 객체도 오류 없게 나옴 주의

 type CountryNumberCodes = {
   [key: string]: number;
   Korea: string; // 오류!
  };

=> 두개 value 값은 같아야 한다!!!!

 

7-8. enum

여러가지 값들이 가각 이름을 열거해두고 사용하는 타입
enum Role {
  ADMIN,
  USER,
  GUEST,
}

enum Language {
  korean = "ko",
  english = "en",
}

=> 자동으로 0,1,2 할당 가능 지정도 가능

=>USER =10 (숫자형 이넘)을 만들면 0 , 10 , 11 할당

const user1 = {
  name: "이정환",
  role: Role.ADMIN, //0 관리자자
  language: Language.korean,
};

const user2 = {
  name: "홍길동",
  role: Role.USER, // 1 일반 유저
};

const user3 = {
  name: "아무게",
  role: Role.GUEST, //2 게스트
};

 

타입스크립트의 enum 은 type과 다르게 값이 사라지지 않아서
값처럼 사용이 가능하다!! (role: Role.ADMIN)

 

7-9. any

특정 변수의 타입을 우리가 확실히 모를때
어떤 타입이든지 넣을 수 있음
let anyVar: any = 10;
anyVar = "hello";
anyVar = true;
anyVar = {};

 

변수 저장도 가능

let num: number = 10;
num = anyVar;

 

=> 타입  에러는 없지만 실행 시 오류가 떠서 사용 자제!!!!

 

7-10. unknown

unknown 타입은 any 타입과 비슷하지만 보다 안전한 타입
어떤 타입의 값이든 다 저장
let unknownVar: unknown;
unknownVar = "";
unknownVar = 1;
unknownVar = () => {};

 

!!!!unknown 타입의 값은 어떤 타입의 변수에도 저장할 수 없다

num = unknownVar; // 오류 !

 

7-11. void 

아무것도 없음을 의미

 

함수의 반환값 지정이 가능함

function func1(): string {
  return "hello";
}

 

반환값이 없는 경우 함수를 지정 할 때 void를 사용!!!
function func2(): void {
  console.log("hello");
}

 

왜 undefined는 안돼?

함수가 진짜 undefined 을 반환
따라서 return문 자체가 없는 함수의 반환값 타입을 정의해야 할 때에는 void 타입을 이용

 

7-12 never

불가능한 타입
정상적으로 종료가 안되는 반환이 안되는 함수
function func3(): never {
  while (true) {}
}

//모순 에러
function func4(): never {
  throw new Error();
}

 

=> never 타입은 진짜 암것도 못담음

=> strickNullCheck 꺼도 null도 못담음


타입을 정할 때 봐야 하는 것!!!!

어떤 기준으로 타입 정의
어떤 기준으로 타입간의 관계 정의
어떤 기준으로 타입의 오류를 검사하는지

 

8. 타입 = 집합

 

타입은 집합!!!!!
여러개의 요소 원소를 하나로 묶어 놓은 것!!!!!!!

 

동일한 속성과 특성을 모아놓은 집합 = number type

let num:20 =20;

=> 20 1개만 포함하고 있는 집합?
=> 20은 number type 즉 number literal Type 서브타입(자식 타입)
=> number type 슈퍼타입(부모타입)
타입스크립트가 제공하는 여러가지 기본 타입들간의 집합으로써의 부모-자식 관계 

 

타입 호환성!!!!

: 어떤 타입을 다른 타입으로 취급해도 괜찮은지 판단

let num1: number = 10;
let num2: 10 = 10;

num1 = num2; //  업캐스팅
num2 = num1; //  다운캐스팅 //이건 안돼!!!

 

서브타입의 값을 슈퍼타입으로 취급하는 건 괜찮지만 => 업캐스팅
슈퍼타입을 서브타입으로 보는건 안돼!!!!!!! => 다운캐스팅

 

- 타입 계층도!!!

한입 타입스크립트

8-1 Unknown

전체집합!!! 가장 슈퍼 타입
업캐스팅은 전부 가능 하므로 전체 집합인 unknown은 모든 걸 지정 가능
function unknownExam() {
  let a: unknown = 1; // number -> unknown
  let b: unknown = "hello"; // string -> unknown
  let c: unknown = true; // boolean -> unknown
  let d: unknown = null; // null -> unknown
  let e: unknown = undefined; // undefined -> unknown
  let f: unknown = []; // Array -> unknown
  let g: unknown = {}; // Object -> unknown
  let h: unknown = () => {}; // Function -> unknown

  let unknownValue: unknown;

  //다운 캐스팅은 안돼!!!
  //   let num: number = unknownValue;
  //   let str: string = unknownValue;
  //   let bool: boolean = unknownValue;
  // 오류 : unknown 타입은 number 타입에 할당할 수 없습니다.
}

 

8-2 Never 타입

모든 집합의 서브타입 / 모든 집합의 부분집합!!
반환할 수 있는 값이 아무것도 없다!! 
=> 공집합
function neverExam() {
  function neverFunc(): never {
    while (true) {}
  }

  //업캐스팅으로 가능 never은 모두의 서브집합
  let num: number = neverFunc();
  let a: number = neverFunc();
  let b: string = neverFunc();
  let c: boolean = neverFunc();

  //다운캐스팅으로 안됌!!
  // 그 어느 값도 넣을 수 없음음
  //   let never1: never = 10;
  //   let never2: never = "string";
}

 

8-3 void 타입

void는 undefined의 부모 return 으로 undefined 사용 가능!!
function voidExam() {
  function voidFunc(): void {
    console.log("hi");
    return undefined;
  }

  let voidVAr: void = undefined;
}

 

8-4 any 타입

: 치트키 타입
모든 타입의 슈퍼타입으로 위치하기도 하고
모든 타입의 서브타입으로 위치하기도 한다!!(never만 빼공)
function anyExam() {
  let unknownVar: unknown;
  let anyVar: any;
  let undefinedVar: undefined;
  let neverVAr: never;

  //? 다운캐스팅인데 왜 되는거지?
  //=> any는 돼!!!!!!!
  //자기 자신이 다운 오키 다른 애들이 다운 오키키
  anyVar = unknownVar;
  undefinedVar = anyVar;

//   neverVAr = anyVar; //오류 never은 순수한 공집합 그 어떤 것도 다운캐스팅 안돼!
}

=> 위험해서 왠만하면 쓰지망

 

8-5 기본 타입간의 호환성

let num1: number = 10;
let num2: 10 = 10;

//업캐스팅
num1 = num2;

 

8-6-1 객체 타입간의 호환성

type Animal = {
  name: string;
  color: string;
};

type Dog = {
  name: string;
  color: string;
  breed: string;
};

let animal: Animal = {
  name: "기린",
  color: "yellow",
};

let dog: Dog = {
  name: "돌돌이",
  color: "brown",
  breed: "진도",
};

 

animal = dog;
// dog = animal; //오류!!!!!

 

객체 또한 기본타입 처럼 서브 슈퍼 타입을 가짐

 

 

  • 객체도 기본 타입처럼 서브 타입과 슈퍼 타입의 관계를 가짐
  • TypeScript는 구조적 타입 시스템

=> 객체의 속성 구조가 기준이 되어 타입 간의 관계를 판단한다.

name과 color 속성이 있는 타입은 Animal이라는 슈퍼 타입
Dog 타입은 name, color에 더해 breed 속성까지 포함하므로 Animal의 서브 타입
더 많은 속성을 가진 타입이 서브 타입, 조건이 더 적은 타입이 슈퍼 타입이 된다.

 

8-6-2 초과 프로퍼티 검사

실제 작성하지 않은 프로퍼티의 값이 작성되면 막음
딱 객체 타입에 지정된 값만 넣을 수 있음
//슈퍼타입
type Book = {
  name: String;
  price: number;
};

//서브타입
type ProgrammingBook = {
  name: String;
  price: number;
  skill: string;
};

let book: Book;

let programmingBook: ProgrammingBook = {
  name: " 열심히해",
  price: 3300,
  skill: "react",
};

 

 

왜 book = programmingBook;이건되는데 초과프로퍼티 검사로 아래는 안됌

let book2: Book = {
  name: " 열심히해",
  price: 3300,
  //   skill: "react", //오류
};

 

- 객체에 넣지 않아서 가능

let book3: Book = programmingBook;
//객체에 넣은건 아니라 가능ㅋ

 

- 함수에 인수로 전달 할때도 안돼!!
  서브타입 리터럴을 할때는 인수로 전달해!!!!

function func(book: Book) {}

func({
  // 오류 발생
  name: "한 입 크기로 잘라먹는 리액트",
  price: 33000,
  //   skill: "reactjs",
});

func(programmingBook); //이렇게 인수로 넣는건 ok

'React' 카테고리의 다른 글

React Context API와 LocalStorage로 상태 관리  (0) 2025.04.23
Context 알아보기  (0) 2025.04.22
TanStack Query (React Query) 알아보기  (0) 2025.04.21
Axios와 async/await  (2) 2025.04.16
React & Next.js 활용해보기 / CSR vs SSR  (1) 2025.04.14
'React' 카테고리의 다른 글
  • React Context API와 LocalStorage로 상태 관리
  • Context 알아보기
  • TanStack Query (React Query) 알아보기
  • Axios와 async/await
startfront
startfront
startfront 님의 블로그 입니다.
  • startfront
    startfront 님의 블로그
    startfront
  • 전체
    오늘
    어제
    • 분류 전체보기 (42) N
      • 프로젝트 (5) N
        • 프로젝트 해보기 (1) N
        • 디자인 알아보기 (2)
        • 프로젝트의 기본 (2)
      • 백엔드의 이해 (4)
      • React (14)
      • 프론트엔드 기본 (2)
        • Html (1)
        • Css (0)
        • JavaScript (1)
      • Cs기본지식 (14)
        • 알고리즘 (8)
        • 데이터베이스 (6)
      • Java (3)
        • Java의 이해 (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
startfront
타입스크립트 사용법과 기본 타입 정리
상단으로

티스토리툴바