TypeScript

[ TypeScript ] 기본 타입

변쌤(이젠강남) 2024. 11. 14. 11:34
반응형

기본 타입

 

1. unknown

  • 모든 타입의 슈퍼 타입으로, 모든 값이 할당될 수 있습니다.
  • 타입이 명확하지 않을 때 사용하지만, any와 달리 제한적입니다. 사용하기 전 명확한 타입으로 좁히는 타입 가드가 필요합니다.

 

2. any

  • 모든 타입을 허용하는 타입으로, 타입 검사를 건너뛰는 역할을 합니다.
  • 타입 안정성을 낮출 수 있으므로 가능한 사용을 자제하는 것이 좋습니다.

 

3. 기본 타입들

  • null: null 값만 가질 수 있는 타입입니다.
  • void: 함수가 값을 반환하지 않을 때 주로 사용되는 타입입니다.
  • number: 숫자 타입이며, Number Enum을 포함합니다.
  • bigint: 큰 정수를 표현하는 타입으로, 일반 숫자보다 큰 정수를 다룰 때 사용됩니다.
  • boolean: true 또는 false의 불리언 값을 가지는 타입입니다.
  • string: 문자열 타입으로, String Enum을 포함합니다.
  • symbol: 심볼 타입으로, Unique Symbol을 포함합니다.
  • object: 객체 타입을 나타내며, Array, Function, Constructor와 같은 구체적인 타입을 포함합니다.

 

4. 유형별 세부 타입

  • undefined: 정의되지 않은 상태를 나타내며, void나 null 타입과 함께 사용됩니다.
  • Number Enum / String Enum: 각각 숫자 또는 문자열 열거형을 나타냅니다.
  • Unique Symbol: 고유한 심볼 값을 나타냅니다.
  • Array: 배열 타입입니다.
  • Function: 함수 타입입니다.
  • Constructor: 생성자 함수 타입을 나타냅니다.

5. never

  • 절대 도달할 수 없는 값을 의미하는 타입입니다. 보통 오류를 발생시키거나 끝없이 실행되는 함수에 사용됩니다.

 

 

 

 

 

 

  • unknown은 모든 타입의 최상위에 위치하며 모든 값을 포함할 수 있습니다.
  • any는 unknown 바로 아래에 있으며, 타입 검사를 우회하는 타입입니다.
  • 기본 타입들인 null, void, number, bigint, boolean, string, symbol, object가 각각의 하위 타입을 가집니다.
  • never는 undefined와 null의 하위 타입으로, 도달할 수 없는 값을 나타냅니다.

 

 

 

 

# 원시타입과 리터널 타입

 

 

  • 원시 타입은 기본적인 데이터 타입으로 number, string, boolean 등 JavaScript와 동일한 타입을 포함합니다.
  • 리터럴 타입은 고정된 값을 가지도록 제한하는 타입으로, 유니온 타입과 결합하여 특정 값들 중 하나만 가질 수 있도록 할 수 있습니다.

 

 

1. 원시 타입 (Primitive Type)

원시 타입은 JavaScript와 TypeScript에서 기본적으로 제공하는 가장 작은 단위의 데이터 타입입니다. 원시 타입은 그 자체로 값을 가지며, 주로 불변(immutable)합니다.

 

number: 숫자 타입을 나타내며, 정수와 소수를 포함합니다.

let age: number = 30;

 

 

string: 문자열 타입을 나타냅니다.

let name: string = "John";

 

boolean: 불리언 타입으로, true 또는 false 값을 가집니다.

let isStudent: boolean = false;

 

bigint: 매우 큰 정수를 표현할 수 있는 타입입니다. BigInt 객체를 사용하거나 숫자 뒤에 n을 붙여 선언할 수 있습니다. (ES2020부터 지원)

let largeNumber: bigint = 9007199254740991n;

 

 

symbol: 고유한 심볼 값을 가지는 타입입니다. 객체의 고유한 속성 키를 만들 때 유용합니다.

let uniqueKey: symbol = Symbol("key");

 

 

undefined: 변수는 선언되었으나 값이 할당되지 않았을 때 기본적으로 가지는 타입입니다.

let notAssigned: undefined = undefined;

 

null: 값이 없음을 명시적으로 나타내는 타입입니다.

let empty: null = null;

 

void: 주로 함수에서 반환 값이 없음을 나타낼 때 사용합니다.

function logMessage(): void {
    console.log("Hello, TypeScript");
}

 

 

never: 절대 도달할 수 없는 값을 나타내는 타입으로, 항상 오류를 발생시키거나 영원히 실행되는 함수에서 사용됩니다.

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

 

 

2. 리터럴 타입 (Literal Type)

리터럴 타입은 변수가 가질 수 있는 고정된 값을 특정할 때 사용됩니다. 예를 들어, 문자열 "hello"를 리터럴 타입으로 지정하면, 그 변수는 "hello" 외의 값으로 변경할 수 없습니다. 리터럴 타입은 주로 문자열, 숫자, 불리언 값으로 사용할 수 있으며, 유니온 타입과 결합하여 여러 개의 고정된 값 중 하나만 허용하는 형태로 활용할 수 있습니다.

 

문자열 리터럴 타입

let direction: "left" | "right" | "up" | "down";
direction = "left";  // 가능
direction = "right"; // 가능
direction = "forward"; // 오류 발생, 지정된 값이 아님

 

 

숫자 리터럴 타입

let statusCode: 200 | 404 | 500;
statusCode = 200; // 가능
statusCode = 300; // 오류 발생, 지정된 값이 아님

 

 

불리언 리터럴 타입

let isCompleted: true | false;
isCompleted = true; // 가능
isCompleted = false; // 가능

 

type TrafficLight = "red" | "yellow" | "green";

function getTrafficLightAction(light: TrafficLight) {
    switch (light) {
        case "red":
            return "stop";
        case "yellow":
            return "slow down";
        case "green":
            return "go";
    }
}

console.log(getTrafficLightAction("red")); // "stop"

 

 

 

 

 

 

# 배열과 튜플

 

 

  • 배열(Array): 동일한 타입의 값을 여러 개 가질 수 있는 구조. number[] 또는 Array<number> 형태로 선언.
  • 튜플(Tuple): 고정된 개수와 타입의 값을 가질 수 있는 구조. [string, number] 형태로 선언.

 

 

 

1. 배열 (Array)

배열은 동일한 타입의 값들을 한 변수에 저장할 수 있는 데이터 구조입니다. JavaScript의 배열과 유사하며, TypeScript에서는 배열에 타입을 지정할 수 있습니다.

 

배열 선언 방법

대괄호([]) 표기법을 사용하여 배열 타입을 지정

let numbers: number[] = [1, 2, 3, 4, 5];
let fruits: string[] = ["apple", "banana", "orange"];

 

 

Array<> 제네릭 표기법을 사용하여 배열 타입을 지정

let numbers: Array<number> = [1, 2, 3, 4, 5];
let fruits: Array<string> = ["apple", "banana", "orange"];

 

배열의 타입 검사

TypeScript는 배열 요소의 타입을 체크하기 때문에, 배열에 잘못된 타입의 값을 추가하려고 하면 오류가 발생합니다.

let names: string[] = ["Alice", "Bob"];
names.push("Charlie");  // 가능
names.push(123);        // 오류 발생, 숫자는 허용되지 않음

 

 

2. 튜플 (Tuple)

튜플은 배열과 비슷하지만, 요소의 타입과 길이를 고정할 수 있습니다. 즉, 튜플은 각 요소의 타입과 순서가 미리 결정된 배열입니다. 이를 통해 각 위치에 특정 타입의 값만 저장하도록 강제할 수 있습니다.

튜플은 정해진 위치에 정해진 타입의 값이 들어가야 하는 데이터를 표현할 때 유용합니다.

튜플 선언 방법

튜플은 대괄호([]) 안에 각 요소의 타입을 순서대로 나열하여 선언합니다.

let person: [string, number] = ["Alice", 30];
let person: [string, number] = ["Alice", 30];   // 가능
let person2: [string, number] = [30, "Alice"];  // 오류 발생, 순서가 다름
let person3: [string, number] = ["Alice", "30"]; // 오류 발생, 타입이 다름

 

 

예)

function fetchData(): [boolean, string] {
    return [true, "Data fetched successfully"];
}

let result = fetchData();
console.log(result[0]); // true
console.log(result[1]); // "Data fetched successfully"

 

 

튜플과 배열의 차이점

특징배열(Array)튜플(Tuple)

특징 배열(Array) 튜플(Tuple)
타입 일관성 배열의 모든 요소가 동일한 타입이어야 함 요소마다 서로 다른 타입을 가질 수 있음
길이 고정 여부 길이 제한이 없음 길이와 각 요소의 타입이 고정됨
사용 목적 동일한 타입의 값 집합 고정된 구조와 순서가 필요한 데이터 그룹

 

 

3. 튜플에 선택적 요소와 나머지 요소 지정

TypeScript에서는 튜플에 선택적 요소(?)나 나머지 요소(...)를 사용할 수도 있습니다.

 

선택적 요소: 특정 요소가 있어도 되고 없어도 되는 경우

let tupleWithOptional: [string, number?] = ["Alice"];      // 가능
tupleWithOptional = ["Alice", 30]; // 가능

 

나머지 요소: 나머지 요소를 특정 타입의 배열로 받을 수 있음

let tupleWithRest: [string, ...number[]] = ["Alice", 10, 20, 30];

 

 

 

 

# 객체

 

 

  • 객체 타입: { 속성: 타입; } 형식으로 객체의 속성 타입을 정의합니다.
  • 선택적 속성: 속성 뒤에 ?를 붙여 선택적으로 설정할 수 있습니다.
  • 읽기 전용 속성: readonly 키워드로 설정하여 값을 변경하지 못하게 할 수 있습니다.
  • 인덱스 시그니처: [key: string]: 타입으로 여러 동적 속성을 가질 수 있습니다.
  • 인터페이스: 객체 타입을 정의하고, 확장할 수 있습니다.
  • 타입 별칭: 타입을 정의하고 확장할 수 있습니다.

 

 

1. 객체 타입 선언 방법

객체의 타입을 정의할 때는 각 속성의 이름과 타입을 지정합니다.

 

let person: { name: string; age: number; isStudent: boolean } = {
  name: "Alice",
  age: 30,
  isStudent: true
};

person 객체는 name, age, isStudent라는 속성을 가지며, 각각 string, number, boolean 타입을 가지고 있습니다.

 

2. 선택적 속성(Optional Properties)

객체의 속성 중 일부는 **선택적(optional)**으로 지정할 수 있습니다. 선택적 속성은 있어도 되고 없어도 되는 속성을 의미하며, 타입 선언에서 속성 이름 뒤에 ?를 붙여서 표시합니다.

let person: { name: string; age?: number } = {
  name: "Alice"
};

age 속성은 선택적이므로 person 객체에 age가 없어도 오류가 발생하지 않습니다.

 

 

3. 읽기 전용 속성(Readonly Properties)

객체의 속성에 읽기 전용(readonly) 제약을 추가하여, 초기화 이후에는 속성의 값을 변경할 수 없도록 할 수 있습니다. readonly 키워드를 속성 앞에 붙여서 사용합니다.

let person: { readonly name: string; age: number } = {
  name: "Alice",
  age: 30
};

person.age = 31;      // 가능
person.name = "Bob";  // 오류 발생, name은 읽기 전용 속성

 

 

4. 인덱스 시그니처 (Index Signature)

객체가 동적 속성을 가질 수 있도록, 특정 타입의 속성을 임의의 이름으로 지정할 때는 인덱스 시그니처를 사용합니다. 주로 속성 이름을 모르는 경우나, 동일한 타입의 여러 속성을 가질 수 있는 객체에 유용합니다.

let dictionary: { [key: string]: string } = {};
dictionary["hello"] = "안녕하세요";
dictionary["goodbye"] = "안녕히 가세요";

dictionary 객체가 문자열을 키로 하고, 문자열을 값으로 가지는 여러 속성을 가질 수 있음을 나타냅니다.

 

5. 객체 타입을 위한 인터페이스 (Interface)

객체 타입이 복잡하거나 여러 곳에서 재사용할 때는 **인터페이스(interface)**를 사용하여 타입을 정의할 수 있습니다. 인터페이스는 객체의 구조를 명확하게 정의해주며, 확장이 가능합니다.

interface Person {
  name: string;
  age: number;
  isStudent?: boolean; // 선택적 속성
}

let alice: Person = {
  name: "Alice",
  age: 30
};

 

 

6. 객체 타입을 위한 타입 별칭 (Type Alias)

인터페이스와 비슷하게 타입 별칭(type alias)도 객체 타입을 정의하는 데 사용됩니다. 인터페이스와의 차이점은 주로 유니온 타입이나 복합 타입을 정의할 때 유용하다는 점입니다.

type Person = {
  name: string;
  age: number;
  isStudent?: boolean;
};

let bob: Person = {
  name: "Bob",
  age: 25
};

 

 

7. 객체 타입을 확장 (Interface & Type Alias Extension)

객체 타입을 확장해서 다른 타입의 기반으로 사용할 수 있습니다.

인터페이스 확장

인터페이스는 상속이 가능하여 다른 인터페이스를 확장할 수 있습니다.

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

interface Employee extends Person {
  jobTitle: string;
}

let employee: Employee = {
  name: "Charlie",
  age: 40,
  jobTitle: "Developer"
};

 

 

타입 별칭 확장

타입 별칭은 & 연산자를 사용하여 여러 타입을 합칠 수 있습니다.

type Person = {
  name: string;
  age: number;
};

type Employee = Person & {
  jobTitle: string;
};

let employee: Employee = {
  name: "Daisy",
  age: 35,
  jobTitle: "Designer"
};

 

 

 

 

# 열거형 

 

 

  • 숫자형 열거형: 자동으로 1씩 증가된 숫자 값을 할당받으며, 값과 이름 간 양방향 매핑이 가능합니다.
  • 문자열 열거형: 각 멤버에 명시적으로 문자열 값을 할당해야 하며, 양방향 매핑은 불가능합니다.
  • 이종 열거형: 숫자와 문자열을 혼합하여 사용할 수 있지만, 특별한 경우가 아니면 권장되지 않습니다.
  • const 열거형: 컴파일 타임에 상수 값으로 대체되며, 성능 최적화를 위해 사용할 수 있습니다.

 

 

 

1. 숫자형 열거형 (Numeric Enum)

숫자형 열거형은 기본적으로 숫자 값을 자동으로 할당하는 열거형입니다. 첫 번째 값에만 숫자를 지정하면, 나머지는 1씩 증가된 값을 자동으로 할당받습니다.

enum Direction {
    Up,       // 0
    Down,     // 1
    Left,     // 2
    Right     // 3
}

let move: Direction = Direction.Up;
console.log(move);  // 0

Direction.Up의 값은 0이고, Down은 1, Left는 2, Right는 3으로 자동 할당

 

enum Status {
    Success = 1,
    InProgress,    // 2
    Failed         // 3
}

console.log(Status.Success);     // 1
console.log(Status.InProgress);  // 2
console.log(Status.Failed);      // 3

 

 

숫자형 열거형의 양방향 매핑

숫자형 열거형은 값과 이름 모두로 접근할 수 있어 양방향 매핑이 가능

enum Status {
    Success = 1,
    InProgress,
    Failed
}

console.log(Status.Success);       // 1
console.log(Status[1]);            // Success

 

 

2. 문자열 열거형 (String Enum)

문자열 열거형은 각 열거형 멤버에 문자열 값을 명시적으로 지정할 수 있는 열거형입니다. 문자열 열거형은 숫자형 열거형과 달리 자동 증분되지 않으며, 항상 지정된 문자열 값만 가집니다.

 

enum Direction {
    Up = "UP",
    Down = "DOWN",
    Left = "LEFT",
    Right = "RIGHT"
}

let move: Direction = Direction.Up;
console.log(move);  // "UP"

문자열 열거형은 특정 문자열 값만 가질 수 있으므로, 값과 이름 간의 양방향 매핑이 불가능합니다. 즉, Direction["UP"]처럼 값을 통해 열거형 이름을 가져올 수 없습니다.

 

3. 이종 열거형 (Heterogeneous Enum)

숫자형문자열형을 혼합하여 사용할 수도 있습니다. 이를  이종 열거형(Heterogeneous Enum)이라고 합니다. 그러나 실제로 이종 열거형은 특수한 경우가 아니면 잘 사용되지 않습니다. 타입 안전성을 저해할 수 있기 때문입니다.

 

enum Result {
    Success = 1,
    Failure = "FAILURE"
}

console.log(Result.Success);  // 1
console.log(Result.Failure);  // "FAILURE"

 

 

4. 열거형의 활용 예시

열거형은 코드의 가독성을 높이고, 고정된 값 집합을 관리하는 데 유용합니다. 주로 상태, 방향, 색상 등 유한한 값들을 표현할 때 많이 사용됩니다.

enum HttpStatus {
    OK = 200,
    BadRequest = 400,
    Unauthorized = 401,
    NotFound = 404,
    InternalServerError = 500
}

function handleRequest(status: HttpStatus) {
    switch (status) {
        case HttpStatus.OK:
            console.log("Request was successful.");
            break;
        case HttpStatus.NotFound:
            console.log("Resource not found.");
            break;
        case HttpStatus.InternalServerError:
            console.log("Server encountered an error.");
            break;
        default:
            console.log("Unhandled status code:", status);
    }
}

handleRequest(HttpStatus.OK);            // "Request was successful."
handleRequest(HttpStatus.NotFound);       // "Resource not found."
handleRequest(HttpStatus.InternalServerError); // "Server encountered an error."

 

 

5. const 열거형 (Const Enum)

const 열거형은 컴파일 타임에 인라인 처리되는 열거형입니다. 즉, 자바스크립트 코드로 컴파일될 때 실제 열거형 객체를 생성하지 않고 상수 값으로 대체됩니다. 성능 최적화가 필요할 때 사용됩니다.

const enum Direction {
    Up,
    Down,
    Left,
    Right
}

let move = Direction.Up;
console.log(move);  // 0 (컴파일된 JavaScript에서는 단순히 상수 값으로 대체)

const enum은 TypeScript에서만 인식 가능하며, 열거형 값이 자바스크립트 코드에서 직접 상수 값으로 변환되어 성능을 최적화할 수 있습니다.

반응형

'TypeScript' 카테고리의 다른 글

[ TypeScript ] 개념 , 컴파일 옵션 설정  (0) 2024.11.14