본문 바로가기

프로그래밍기초/typescript

#03 TypeScript - 변수(원시타입과 리터럴 타입)

원시타입 (Primitive Types)

원시 타입이란 더 이상 분해할 수 없는 가장 기본적인 값의 타입을 의미한다.
값 자체가 메모리에 직접 저장되며 (객체의 주소가 저장되지 않는다) 참조(reference)가 아닌 값(value)으로 취급되는 타입이다.
즉, "하나의 값 그 자체"를 표현하는 타입이다.

TypeScript의 원시 탕타입으로는

타입 설명
number 모든 숫자
string 문자열
boolean true / false
bigint 매우 큰 정수
symbol 고유 식별자
null 값 없음
undefined 정의되지 않음
void 반환값 없음
never 절대 발생하지 않음
literal 특정 값만 허용

 

원시타입의 특징

1) 값 자체를 복사한다.

원시 타입을 변수에 할당하면 값이 그대로 복사된다.

let a = 10;
let b = a;

b = 20;
  • a는 여전히 10이다.
  • 서로 영향을 주지 않는다.

2) 불변성(immutable)

원시 타입의 값은 변경할 수 없다.

let str = "abc";
str[0] = "z"; // 변경 불가
  • 바뀌는 것처럼 보일 경우 -> 실제로는 새 값이 생성됨.

3) 객체가 아니다.

원시 타입은 메서드나 프로퍼티를 가질 수 없다.

let n = 10;
n.toFixed(2); // 가능해 보이지만
  • 내부적으로 임시 객체가 생성되어 처리됨
  • 원시 값 자체는 여전히 객체가 아님

 

타입스크립트의 원시타입 종류

1) number 타입

숫자 타입이다. 정수와 실수를 구분하지 않으며, JavaScript의 number 타입을 그대로 따른다.

let num1: number = 10;
let num2: number = -20;
let num3: number = 0.14;
let num4: number = -0.14;
let num5: number = Infinity;
let num6: number = -Infinity;
let num7: number = NaN;

//num1 = "hello"; // error
num2.toFixed(); // ok
  • 정수, 부동소수점 모두 포함된다.
  • NaN, Infinity도 number에 포함된다.

2) bigint

아주 큰 정수를 표현하기 위한 타입이다. number가 표현할 수 없는 범위의 정수를 다룰 때 사용한다.

let big: bigint = 9007199254740991n;
  • 끝에 n을 붙여야 함
  • number 타입과 혼합 연산 불가

3) string 타입

문자열 타입이다. 작은따옴표('), 큰따옴표("), 백틱(```) 모두 사용 가능하다.

let str1:string = "Hello";
let str2: string = 'World!';
let str3: string = `Hello World!`;
let str4: string = `${str1}, ${str2} !! ㅎㅎㅎ`;

4) boolean 타입

논리 타입이다. 참(true)과 거짓(false)만 허용한다.

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

5) symbol 타입

고유하고 변경 불가능한 식별자를 생성하는 타입이다. 주로 객체의 고유 키로 사용된다.

let sym: symbol = Symbol("id");
  • 동일한 설명 문자열을 사용해도 서로 다른 값임

6) null 타입

값이 없음을 명시적으로 표현하는 타입이다.

let null1: null = null;
  • tsconfig.json에 compilerOptions에 strictNullChecks 옵션이 켜져 있으면 다른 타입에 자동으로 할당되지 않음
    let name: string = null;
    일반적으로 타입스크립트에서는 string 타입에 null을 넣으면
    "Type 'null' is not assignable to type 'string'." 이라는 에러를 발생한다.
    {
      "compilerOptions": {
          ...
          "strict": true,
          "strictNullChecks": false,
          ...
      }
    }
  • 설정파일에서(tsconfig.json) 컴파일옵셔을 수정해주면 null 할당이 가능하다
  • null 타입 변수에 할당

strict 옵션은 strictNullChecks 옵션의 상위옵션이라 strictNullChecks를 사용하려면 strict 는 무조건 true로 해줘야 한다.
strictNullCheck 옵셥은 true default이기 때문에 선언을안하면 자동으로 true로 설정된다.

7) undefined 타입

값이 정의되지 않음을 의미하는 타입이다.

let undef1: undefined = undefined;
  • 초기화되지 않은 변수의 기본값

8) void 타입

엄밀히 말하면 원시 타입이라기보다는 반환값이 없음을 표현하는 타입이다. 함수 반환 타입으로 주로 사용된다.

function log(): void {
  console.log("hello");
}

9) never 타입

절대 발생하지 않는 값을 의미하는 타입이다. 함수가 정상적으로 종료되지 않을 때 사용한다.

function error(): never {
  throw new Error("error");
}
  • 무한 루프
  • 예외를 던지는 함수

10) 리터럴(literal) 타입

원시 타입의 특정 값 하나만 허용하는 타입이다.
타입스크립트는 값자체를 타입으로 줄수 있다.

let v: 10 = 10;
v = 12; // error! 10외엔 다른값 할당 불가.
let v2: "hello" = "hello";
v2 = "hi"; // error! "hello" 이외 할당 불가
let v3: true = false; // error! true만 초기화 가능
  • 문자열, 숫자, boolean 모두 가능
  • 유니온 타입과 함께 자주 사용됨

 

요약

타입 설명
number 모든 숫자
string 문자열
boolean true / false
bigint 매우 큰 정수
symbol 고유 식별자
null 값 없음
undefined 정의되지 않음
void 반환값 없음
never 절대 발생하지 않음
literal 특정 값만 허용

 

배열(Array)

배열(Array)은 같은 타입의 값들을 순서대로 저장하는 자료구조이다.

TypeScript의 배열은 JavaScript 배열을 기반으로 하며,
타입을 명확히 지정할 수 있다는 점이 핵심 차이이다.

 

배열의 종류

1) 기본 문법으로 선언한 배열

let numbers: number[] = [1, 2, 3];
let names: string[] = ["kim", "lee"];
  • 타입[] 형태
  • 가장 직관적이며 실무에서 가장 많이 사용됨

2) 제네릭 문법으로 선언한 배열

let numbers: Array<number> = [1, 2, 3];
  • Array< T> 형태.
  • JSX/React 환경에서는 가독성 때문에 잘 사용하지 않음.
  • 복잡한 제네릭 조합에서는 유용할 수 있음.

3) 유니온 타입 배열

let values: (number | string)[] = [1, "a", 2];
  • 여러 타입을 허용하는 배열
  • 괄호 필수

4) 다차원 배열

let twoDimArr: number [][] = [
  [1, 2, 3],
  [4, 5],
  [6]
]
  • number[][] -> 2차원 배열
  • 차원이 늘어날수록 []도 증가

5) 객체 배열

type User = {
  id: number;
  name: string;
};

let users: User[] = [
  { id: 1, name: "Kim" },
  { id: 2, name: "Lee" }
];

6) readonly 배열

배열의 변경을 막고 싶을 때 사용한다.

let nums: readonly number[] = [1, 2, 3];

nums.push(4); // ❌ 에러
nums[0] = 10; // ❌ 에러
let nums: ReadonlyArray<number> = [1, 2, 3];

 

이렇게 선언해도 된다.

  • 불변 데이터 구조를 강제할 수 있음
  • 함수 파라미터에서 특히 유용함

 

배열의 타입 안정성

TypeScript 배열은 선언된 타입만 허용한다.

let numbers: number[] = [1, 2, 3];

numbers.push(4);     // 가능
numbers.push("5");  // ❌ 컴파일 에러
  • JavaScript에서는 런타임 에러지만
  • TypeScript에서는 컴파일 단계에서 차단됨

 

배열과 타입 추론

TypeScript는 배열에서도 타입을 자동 추론한다.

let nums = [1, 2, 3];
// nums: number[]
let mixed = [1, "a"];
// mixed: (number | string)[]

단, 빈 배열은 주의해야 한다.

let arr = [];
// arr: any[]

→ 반드시 타입 명시 권장

let arr: number[] = [];

 

 

배열을 다루는 메서드와 타입

TypeScript는 배열 메서드의 반환 타입도 정확히 추론한다.

let nums = [1, 2, 3];

nums.map(n => n.toString());
// 반환 타입: string[]
nums.filter(n => n > 1);
// 반환 타입: number[]

 

 

 

 

반응형