[TS] 타입스크립트의 기본 타입

2024. 2. 16. 14:43· Front-end/TypeScript
목차
  1. 1. 기본 타입(Basic Types)이란?
  2. 2. 원시타입 (Primitive Type)
  3. 2.1 number  타입
  4. 2.2 string 타입
  5. 2.3 boolean 타입
  6. 2.4 null 타입
  7. 2.5 undefined 타입
  8. 3. 리터럴 타입
  9. 4. 배열과 튜플
  10. 4.1 배열 타입 정의 방법
  11. 4.2 다양한 타입 요소를 갖는 배열 타입 정의하기
  12. 4.3 다차원 배열 타입 정의하기
  13. 4.4 튜플 
  14. 5. 객체
  15. 5.1 객체 타입을 정의하는 방법
  16. 5.2 선택적 프로퍼티(Optional Property)
  17. 5.3 읽기전용 프로퍼티(Readonly Property)
  18. 6. 인덱스 시그니쳐(Index Signature)
  19. 7. 열거형(Enum) 타입
  20. 7.1 숫자 열거형 타입
  21. 7.2 문자열 열거형 타입
  22. 8. any와 unknown 
  23. 8.1 any 타입
  24. 8.2 Unknown 타입
  25. 9. void와 never
  26. 9.1 void 타입
  27. 9.2 never 타입

 

 

1. 기본 타입(Basic Types)이란?

  • 타입스크립트가 자체적으로 제공하는 타입(내장 타입)
  • 타입스크립트가 제공하는 기본 타입들은 계층에 따라 분류한다. 

 

타입계층도

 

  • 각각의 기본 타입들은 서로 부모 자식 관계를 이루며 계층을 형성한다. 

 

2. 원시타입 (Primitive Type)

  • 동시에 한개의 값만 저장할 수 있는 타입
  • 타입을 정의할 때는 변수의 이름 뒤에 콜론(:)과 함께 정의하면 된다. 
  • 이러한 문법을 타입 주석 또는 타입 어노테이션이라고 한다. 

 

2.1 number  타입

// 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;
  • number 타입으로 정의된 변수에는 숫자 이외의 값을 할당 할 수 없으며 toUpperCase등과 같은 문자열에만 사용할 수 있는 메서드를 사용할 수 없다. 

 

2.2 string 타입

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

 

2.3 boolean 타입

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

 

2.4 null 타입

// null
let null1: null = null;
  • 오직 null 값만 포함하는 타입 

 

2.5 undefined 타입

// undefined
let unde1: undefined = undefined;
  • 오직 undefined만 포함하는 타입

 

💡 만약 null 값을 다른 타입의 변수에 할당하고 싶다면?

자바스크립트에서는 아직 값이 정해지지 않은 상태의 변수에 null 값을 임시로 할당하는 경우가 있다. 하지만 타입스크립트라면 어떨까?

 

만약 해당 변수가 number 타입의 변수일 경우 오류가 난다. 따라서 null 값을 변수의 임시 값으로 활용하고 싶다면 컴파일러 옵션을 설정해주면 된다. 

 

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

 

strictNullChecks 옵션은 타입스크립트에서 null 값을 null 타입 이외의 타입의 변수에 할당하는 것을 금지할지 허락할지 여부를 결정하는 옵션이다. 기본값은 true이며 이때는 엄격하게 null 값을 검사해 null 타입이 아닌 경우에는 할당할 수 없도록 한다. false로 설정하면 어떤 타입의 변수든 null 값을 자유롭게 할당할 수 있다. 

 

3. 리터럴 타입

  • 딱 하나의 값만 포함하는 타입
  • 값 자체로 만들어진 타입으로 해당 값 이외의 값은 저장할 수 없다.
let numA: 10 = 10;
let strA: "hello" = "hello";
let boolA: true = true;
let boolB: false = false;

 

4. 배열과 튜플

4.1 배열 타입 정의 방법

let numArr: number[] = [1, 2, 3]
let strArr: string[] = ["hello", "im", "winterlood"];
let boolArr: Array<boolean> = [true, false, true];
  • 배열을 저장하는 변수의 이름 뒤에 콜론(:)을 작성한 다음 배열요소타입[] 형식으로 타입을 정의한다. 
  • 또한, 제네릭을 사용해서 타입을 정의할 수 있다. 

 

4.2 다양한 타입 요소를 갖는 배열 타입 정의하기

// 이렇게 다양한 타입을 갖는 배열의 경우에는?
let multiArr = [1, "hello"];

let multiArr: (number | string)[] = [1, "hello"];
  • 바(|)를 이용해 여러 타입 중 하나를 만족하는 타입 정의
  • 즉, number 타입 혹은 string 타입이어야 한다. 
  • 이러한 문법을 유니온(Union) 타입 이라고 한다.  

 

4.3 다차원 배열 타입 정의하기

let doubleArr : number[][] = [
  [1, 2, 3], 
  [4, 5],
];
  • [] 를 연달아 작성해 타입을 정의할 수 있다. 

 

4.4 튜플 

  • 길이와 타입이 고정된 배열 

 

let tup1: [number, number] = [1, 2];
let tup2: [number, string, boolean] = [1, "hello", true];
  • 예제와 같이 길이가 2로 고정된 튜플 타입을 정의할 수 있다. 
  • 또한, 다양한 타입을 갖는 튜플 타입도 정의할 수 있다. 
  • 튜플은 결국 배열이므로 다양한 배열 메서드를 이용할 수 있다. 즉, push나 pop 메서드를 이용하면 고정된 길이를 무시하고 요소를 추가하거나 삭제할 수 있다. → 사용할 수는 있으나 주의해서 사용해야 한다. 

 

💡 튜플은 왜 사용하는 걸까?

 

예를들어 

const users = [
  ["이정환", 1],
  ["이아무개", 2],
  ["김아무개", 3],
  ["박아무개", 4],
  [5, "조아무개"], // <- 새로 추가함
];

 

기존 users 배열에 1번 인덱스로 이름, 2번 인덱스로 번호를 할당했다. 수많은 사람이 있다고 가정하고 새로운 사람을 추가하려고 할 때 실수로 순서를 바꿔서 추가한다면 튜플은 오류를 발생시켜 문제를 해결할 수 있게한다. 

 

5. 객체

5.1 객체 타입을 정의하는 방법

  • object 타입, 객체 리터럴 타입 이 두 가지 방식으로 객체 타입을 정의 할 수 있다. 

 

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

user.id; // 오류
  • user 객체에 id 프로퍼티가 있음에도 오류가 나는 이유는 object 타입은 단순하게 값이 객체임을 표현하는 것 이외에 아무런 정보도 제공하지 않는 타입이기 때문이다. 따라서 프로퍼티에 접근하려고 하면 오류가 발생한다. 

 

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

user.id;
  • 객체 리터럴 타입으로 정의하면 프로퍼티에 오류 없이 접근할 수 있다. 
  • 객체 타입을 정의할 때는 object 타입보다는 객체 리터럴 타입을 사용하는 것이 좋다. 

 

5.2 선택적 프로퍼티(Optional Property)

let user: {
  id?: number; // 선택적 프로퍼티가 된 id
  name: string;
} = {
  id: 1,
  name: "이정환",
};

user = {
  name: "홍길동",
};
  • 선택적 프로퍼티는 상황에 따라 생략하도록 만들고 싶을 때 사용할 수 있다. 
  • 써도되고 안써도 되는 프로퍼티를 정의하고 싶을 때 프로퍼티 이름 뒤에 ? 물음표를 붙여주면 된다.  

 

5.3 읽기전용 프로퍼티(Readonly Property)

let user: {
  id?: number;
  readonly name: string; // name은 이제 Readonly 프로퍼티가 되었음
} = {
  id: 1,
  name: "이정환",
};

user.name = "dskfd"; // 오류 발생
  • 읽기전용 프로퍼티는 이름 앞에 readonly 키워드를 붙여주면된다. 
  • 의도치 않은 프로퍼티 수정을 방지할 수 있다. 

 

6. 인덱스 시그니쳐(Index Signature)

  • 객체 타입을 유연하게 정의할 수 있도록 돕는 문법

 

type CountryCodes = {
  [key: string]: string;
};

let countryCodes: CountryCodes = {
  Korea: "ko",
  UnitedState: "us",
  UnitedKingdom: "uk",
  // (... 약 100개의 국가)
  Brazil : 'bz'
};
  • 여러 개의 프로퍼티를 추가해야할 때 사용할 수 있다. 
  • [key : string] : string 은 인덱스 시그니처 문법으로 key가 string 타입이고 value가 string 타입인 모든 프로퍼티를 포함한다는 뜻이다. 
  • 즉, 여러 개의 프로퍼티에 일일히 타입을 직접 명시할 필요없이 한번에 타입을 정의할 수 있다. 

 

type CountryNumberCodes = {
  [key: string]: number;
  Korea: number;
};
  • 반드시 포함해야 하는 프로퍼티가 있다면 직접 명시할 수 있다. 

 

🚨 주의할 점

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

 

이와 같이 인덱스 시그니쳐를 사용하면서 동시에 추가적인 프로퍼티를 정의할 때에는 인덱스 시그니쳐의 value 타입과 직접 추가한 프로퍼티의 value 타입이 호환되거나 일치해야된다. 아니면 위와같이 오류가 발생한다. 

 

7. 열거형(Enum) 타입

  • 여러 개의 값을 나열하는 용도로 사용

 

7.1 숫자 열거형 타입

// enum 타입
// 여러가지 값들에 각각 이름을 부여해 열거해두고 사용하는 타입

enum Role {
  ADMIN = 0,
  USER = 1,
  GUEST = 2,
}

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

const user2 = {
  name: "홍길동",
  role: Role.USER, // 회원
};

const user3 = {
  name: "아무개",
  role: Role.GUEST, // 게스트
};
  • user1.role에는 0이 user2.role에는 1이 user3.role에는 2가 할당된다. 
  • 유저의 권한과 같은 여러개의 멤버를 갖는 값을 숫자로 표기할 때 enum을 이용해 보다 안전하고 직관적으로 관리할 수 있다. 
  • 이때 enum 멤버에 숫자 값을 직접 할당하지 않아도 0 부터 1씩 늘어나는 값으로 자동으로 할당된다. 
  • 멤버의 값이 모두 숫자인 enum을 숫자형 enum 혹은 숫자 열거형 타입이라고 한다. 

 

7.2 문자열 열거형 타입

enum Role {
  ADMIN,
  USER,
  GUEST,
}

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

const user1 = {
  name: "이정환",
  role: Role.ADMIN, // 0
  language: Language.korean,// "ko"
};
  • 모든 멤버의 값이 문자열 값인 enum을 문자열 enum 이라고 한다.
  • 문자열 enum을 사용하면 user1.language 같은 프로퍼티에 오타가 있다면 오류가 발생해 실수를 방지 할 수 있다.

 

8. any와 unknown 

8.1 any 타입

  • 타입 검사를 받지 않는 치트키 같은 타입

 

let anyVar: any = 10;
anyVar = "hello";

anyVar = true;
anyVar = {};

anyVar.toUpperCase();
anyVar.toFixed();
anyVar.a;
  • any 타입은 어떠한 타입 검사도 받지 않고 아무 타입의 값이나 범용적으로 담아 사용할 수 있다. 
  • 또한 다양한 타입의 메서드도 마음대로 호출해서 사용할 수 있다. 
  • any 타입의 값은 어떤 타입으로 정의된 변수던 상관없이 다 할당 할 수 있다. 
  • any 타입은 기존의 타입스크립트 문법과 규칙으로부터 자유롭지만 타입검사가 제대로 이루어지지 않기때문에 타입스크립트를 쓰는 이유가 없어지는 타입이라고 할 수 있다. 따라서 어쩔 수 없는 경우를 제외하고 최대한 사용하지 않는것이 좋다. 

 

8.2 Unknown 타입

// unknown 타입의 변수
let unknownVar: unknown;

unknownVar = "";
unknownVar = 1;
unknownVar = () => {};

// unknown 타입의 값
let num: number = 10;
(...)

let unknownVar: unknown;
unknownVar = "";
unknownVar = 1;
unknownVar = () => {};

num = unknownVar; // 오류 !

// 연산 불가능
let unknownVar: unknown;
(...)

unknownVar * 2 // 오류!
  • unknown 타입의 변수는 어떤 타입의 값이든 다 저장할 수 있지만 값은 어떤 타입의 변수에도 저장할 수 없다.  
  • any 타입과 비슷하지만 보다 안전한 타입이다. 
  • unknown 타입의 값은 어떤 연산에도 참여할 수 없으며, 어떤 메서드도 사용할 수 없다.  
  • 즉, 값을 저장하는 일만 수행한다. 

 

💡 만약 unknown  타입의 값을 number 타입의 값처럼 취급하고 연산을 수행하고 싶다면?

if (typeof unknownVar === "number") {
	// 이 조건이 참이된다면 unknownVar는 number 타입으로 볼 수 있음
  unknownVar * 2;
}
  • 조건문을 이용해 특정 값이 특정 타입임을 보장할 수 있게되면 해당 값의 타입이 자동으로 바뀐다. 
  • 이를 타입 좁히기라고 한다. 

 

✍🏼 정리하자면 

특정 변수가 당장 어떤 값을 받게 될 지 모른다면 any 타입으로 정의하는 것 보다는 unknown 타입을 이용하는 것이 훨씬 안전하다. 

 

9. void와 never

9.1 void 타입

  • 아무런 값도 없음을 의미한다. 

 

function func2(): void {
  console.log("hello");
}
  • 아무런 값도 반환하지 않는 함수의 반환값 타입을 정의할 때 사용한다. 

 

let a: void;
a = undefined;
  • 변수의 타입으로도 void 타입을 지정할 수 있다. 
  • void 타입의 변수에는 undefined 이외의 다른 타입의 값은 담을 수 없다. 

 

9.2 never 타입

  • 불가능을 의미하는 타입

 

function func3(): never {
  while (true) {}
}

function func4(): never {
  throw new Error();
}
  • 함수가 어떠한 값도 반환할 수 없는 상황일 때 해당 함수의 반환값 타입을 정의할 때 사용된다. 
  • 예제처럼 무한루프를 도는 함수는 아무런 값도 반환하지 않는 할 수 없는 불가능 상태일 때 never 타입을 사용한다. 
  • 또한 의도적으로 오류를 발생시키는 함수도 never 타입으로 반환값 타입을 사용한다. 
  • never 타입으로 정의하면 any 타입을 포함해 그 어떠한 값도 해당 변수에 담을 수 없다. 

 

 

📌 

한 입 크기로 잘라먹는 타입스크립트(TypeScript)

저작자표시

'Front-end > TypeScript' 카테고리의 다른 글

[TS] 타입을 추론하고... 단언하고... 좁히고...  (0) 2024.02.19
[TS] 타입 별칭(type) vs 인터페이스(interface)  (1) 2024.02.18
[TS] 타입은 집합이다?  (1) 2024.02.17
[TS] 타입스크립트 컴파일러 옵션 알아보기  (0) 2024.02.15
[TS] 꼭 타입스크립트를 사용해야 할까?  (0) 2024.02.14
  1. 1. 기본 타입(Basic Types)이란?
  2. 2. 원시타입 (Primitive Type)
  3. 2.1 number  타입
  4. 2.2 string 타입
  5. 2.3 boolean 타입
  6. 2.4 null 타입
  7. 2.5 undefined 타입
  8. 3. 리터럴 타입
  9. 4. 배열과 튜플
  10. 4.1 배열 타입 정의 방법
  11. 4.2 다양한 타입 요소를 갖는 배열 타입 정의하기
  12. 4.3 다차원 배열 타입 정의하기
  13. 4.4 튜플 
  14. 5. 객체
  15. 5.1 객체 타입을 정의하는 방법
  16. 5.2 선택적 프로퍼티(Optional Property)
  17. 5.3 읽기전용 프로퍼티(Readonly Property)
  18. 6. 인덱스 시그니쳐(Index Signature)
  19. 7. 열거형(Enum) 타입
  20. 7.1 숫자 열거형 타입
  21. 7.2 문자열 열거형 타입
  22. 8. any와 unknown 
  23. 8.1 any 타입
  24. 8.2 Unknown 타입
  25. 9. void와 never
  26. 9.1 void 타입
  27. 9.2 never 타입
'Front-end/TypeScript' 카테고리의 다른 글
  • [TS] 타입 별칭(type) vs 인터페이스(interface)
  • [TS] 타입은 집합이다?
  • [TS] 타입스크립트 컴파일러 옵션 알아보기
  • [TS] 꼭 타입스크립트를 사용해야 할까?
개발중인제이
개발중인제이
개발중인제이
제이로그
개발중인제이
전체
오늘
어제
  • 분류 전체보기 (100)
    • 기록 (6)
      • 회고 (1)
      • TIL (4)
      • 일상 (0)
      • 리뷰 (1)
    • Web (4)
    • Front-end (81)
      • HTML & CSS (4)
      • JavaScript (9)
      • 모던자바스크립트 (14)
      • React (21)
      • Next (6)
      • TypeScript (11)
      • git & github (2)
      • etc (14)
      • 프로젝트 (0)
    • Back-end (0)
    • 알고리즘 & 자료구조 (0)
    • 패스트캠퍼스 (8)
    • 기타 (1)

블로그 메뉴

  • 홈
  • 글쓰기
  • 관리

공지사항

인기 글

최근 글

hELLO · Designed By 정상우.v4.2.2
개발중인제이
[TS] 타입스크립트의 기본 타입
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.