[typeScript] 2. 기본 타입의 종류

yricog·2025년 1월 9일
0

TypeScript

목록 보기
2/2
post-thumbnail

참고 : 한 입 크기로 잘라먹는 타입스크립트 / docs

1. 원시타입과 리터럴타입

원시타입(Primitive Type)

  • 동시에 하나의 값만 저장하는 타입
  • 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;

  // 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
  let null1: null = null;

  // undefined
  let unde1: undefined = undefined;

:number 와 같이 타입을 작성하는 문법을 타입 주석(annotation) 이라 한다.

만약, 다른 타입의 변수에 null 값을 임시로 넣고 싶다면 tsconfig.json에서 "strictNullChecks:false"를 추가 해주면 된다. "strictNullChecks" 옵션은 "strict"옵션의 하위 호환 버전으로 "strict"옵션을 끄면 "strictNullChecks"도 같이 꺼진다.

리터럴 타입

  • 변수의 타입을 값 그 자체로 정의
  let numB: 10 = 10;
  let strA: "hello" = "hello";
  let boolA: true = true;

2. 배열과 튜플

배열

  // 배열
  let numArr: number[] = [1, 2, 3];
  let strArr: string[] = ["hello", "im", "yricog"];
  let boolArr: Array<boolean> = [true, false, true]; // 제네릭 문법

  // 배열 요소의 타입이 다양할 경우
  let multiArr: (number | string)[] = [1, "hello"]; // 유니온 타입

  // 다차원 배열의 타입 정의
  let doubleArr: number[][] = [
    [1, 2, 3],
    [4, 5],
  ];

튜플

  • 길이와 타입이 고정된 배열
  let tup1: [number, number] = [1, 2];
  let tup2: [number, string, boolean] = [1, "2", true];

  /**
   * js로 컴파일하면 일반 배열이기 때문에 배열 메서드 사용 가능!
   * 이 때 push, pop을 사용해도 에러가 나지 않는 것은
   * 길이에 제한을 두지 않기 때문이다.
   */
  tup1.push(1);
  tup1.pop();
  tup1.pop();
  tup1.pop(); // 정상! 

  const users: [string, number][] = [
    ["이아무개", 1],
    ["김수민", 2],
    ["박나래", 3],
    ["김아라", 4],
  ];

3. 객체

  • 객체 리터럴 타입
    • optional property(?) : 옵셔널 속성
    • readonly : 읽기 전용
  let user: {    // 객체 리터럴 타입
    id?: number; // optional property
    name: string;
  } = {
    id: 1,
    name: "yricog",
  };
  
  user.id;
  user = { name: "홍길동" }; // id는 옵셔널 

  let config: {
    readonly apiKey: string; // readonly
  } = {
    apiKey: "API KEY",
  };

  // config.apiKey = "hacked"; 변경 불가능!

타입을 object로 지정하면 객체 안에 object만 남는다.
그래서 user.id 와 같이 속성을 지정하면 없는 속성이 된다.

위와 같이 구조를 기준으로 타입을 정의하는 것을 '구조적 타입 시스템(Property Based Type System)'이라 한다.

4. 타입 별칭과 인덱스 시그니처

타입 별칭(type alias)

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

  let user: User = {
    id: 1,
    name: "jenna",
    nickname: "jj",
    birth: "1999.01.08",
    bio: "안녕하세요",
    location: "서울시",
  };

인덱스 시그니처

  • key-value의 타입이 어떠한 규칙을 갖게 됨
  • 해당 타입은 검사할 객체가 비어 있어도 괜찮다
  type CountryCodes = {
    [key: string]: string; // 인덱스 시그니처, 비어있어도 된다
    Korea: number; // 꼭 필요한 값
  };

  let countryCodes: CountryCodes = {
    UnitedState: "us",    // key가 string이면 어떤걸 추가해도 ok.
    UnitedKingdom: "uk",
    Korea: "ko",  // 없으면 에러 
  };

5. Enum 타입

  • 여러가지 값들에 각각 이름을 부여해 열거해두고 사용하는 타입
  • 값을 지정하지 않으면 자동으로 0부터 숫자가 값으로 부여된다.
  • enum은 type과 다르게 컴파일 시 사라지지 않는다.
  enum Role {
    ADMIN = 0,
    USER = 1,
    GUEST = 2,
  }

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

  const user1 = {
    name: "김이박",
    role: Role.ADMIN, //0
    language: Language.korean,
  };
  
  const user2 = {
    name: "홍길동",
    role: Role.USER, //1
  };
  
  const user3 = {
    name: "아무개",
    role: Role.GUEST, //2
  };

6. Any와 Unknown 타입

any

  • 특정 변수의 타입을 우리가 확실히 모를 때 사용
  • 단점 : 타입 검사를 다 통과한 다음에 런타임에 오류를 낸다.
    • 사실상 타입 검사를 안하는 것과 같으며, 그것은 타입스크립트가 가진 이점을 포기한다는 것.
    • 최대한 사용하지 말기!!
  let anyVar: any = 10;
  
  // 모든 타입 할당 가능 
  anyVar = "hello";
  anyVar = true;
  anyVar = 1;
  anyVar = {};
  anyVar = () => {};

  let num: number = 10;
  num = anyVar;        // ❗️ 모든 타입의 값에 할당되어질 수 있다.

Unknown

  • any처럼 아무 변수에나 할당할 수 없다.
    • any 보다 낫다는 점..
  let unknownVar: unknown;

  // 모든 타입 할당 가능 
  unknownVar = "hello";
  unknownVar = true;
  unknownVar = 1;
  unknownVar = {};
  unknownVar = () => {};

  let num: number = 10;
  num = unknownVar;     // 할당 불가❌

  // 타입 정제 후 할당 가능 
  if (typeof unknownVar === "number") {
    num = unknownVar;
  }

7. Avoid와 Never 타입

void

  • void(= 공허, 아무것도 없음을 의미하는 타입)
  • 오직 undefined만 할당 가능하다.
  • "strictNullChecks"를 false로 하면 null 값도 할당 가능
    • undefined와 null을 타입으로 명시하면 실제로 undefined와 null을 직접 return 해주어야 한다.
  • return문이 필요없는 함수에는 void를 사용하자.
  function func1(): string {
    return "hello";        // string을 리턴
  }

  function func2(): void {
    console.log("hello");  // 그냥 출력문, 아무것도 리턴하지 않음 
  }
  
  let a: void;
  a = 1;         // 할당 불가❌
  a = "hello";   // 할당 불가❌
  a = {};        // 할당 불가❌
  a = undefined; // 오직 undefined만 담을 수 있다

never

  • never(= 존재하지 않는, 불가능한 타입)
  • 함수가 종료될 수 없어서 이 함수에 반환값 자체가 있는게 모순이다! 할 때 사용
  function func3(): never {
    while (true) {} // 무한 루프
  }

  function func4(): never {
    throw new Error(); // 실행 시 프로그램 종료
  }
  
  // ❗️변수에 never 타입을 사용할 순 있지만, 아무런 값도 담을 수 없다.
  let b: never;
profile
의미와 가치를 쫓는 개발자 ✨

0개의 댓글