24. 08. 29 TIL

TypeScript 소개
- 정의: JavaScript의 상위집합 언어로, 정적 타입 시스템 추가
- 장점: 
  - 컴파일 시 타입 오류 발견 가능
  - 대규모 프로젝트에 적합
  - 향상된 개발 경험 (코드 완성, 타입 검사 등)

TypeScript 동작 원리
- 컴파일 과정: TS 코드 분석 → JS 코드로 변환 → 타입 검사
- 주요 단계: 파일 로드, 코드 분석, 심볼 테이블 생성, JS 변환, 타입 검사

## 요약
- TypeScript는 JavaScript에 타입 시스템을 추가한 언어
- 컴파일 시 타입 체크를 통해 안정성 향상
- React와 함께 사용 시, 컴포넌트 props에 타입 지정 가능
- Vite를 이용해 쉽게 React + TypeScript 프로젝트 설정 가능

 


타입 정의

= 타입은 값이 가진 프로퍼티와 메서드 등을 참조하는 방법

= 값이 어떤 속성을 가지고 있는지 표현하는 방법으로 이해할 수 있음

 

타입 정리
## 기본 타입

1. 불린 (boolean)

let isDone: boolean = false;

 

참/거짓을 나타내는 타입. true 또는 false 값만 가질 수 있음.

2. 숫자 (number)

typescript
let decimal: number = 6;
let hex: number = 0xf00d;
let binary: number = 0b1010;
let octal: number = 0o744;


모든 숫자를 나타내는 타입.

3. 문자열 (string)

typescript
let color: string = "blue";
let fullName: string = `Bob Bobbington`;


텍스트 데이터를 나타내는 타입. 작은따옴표, 큰따옴표, 백틱(`)을 사용할 수 있음.

4. 배열 (Array)

typescript
let list: number[] = [1, 2, 3];
let fruits: Array<string> = ["Apple", "Banana", "Mango"];


동일한 타입의 여러 요소를 포함하는 리스트를 나타냄. 두 가지 방법으로 선언할 수 있음.



## 복합 타입

5. 인터페이스 (interface)

typescript 
interface User {
  name: string;
  age: number;
}


객체의 구조를 정의하는 타입. 여러 속성의 이름과 타입을 지정할 수 있음.

6. 타입 별칭 (type)

typescript
type Point = {
  x: number;
  y: number;
};


기존 타입에 새로운 이름을 부여하는 방법. 인터페이스와 비슷하지만 더 다양한 타입을 정의할 수 있음.



## 특수 타입

7. Null과 Undefined

typescript
let u: undefined = undefined;
let n: null = null;


각각 '정의되지 않음'과 '값이 없음'을 나타내는 특수한 타입.

8. Any

typescript
let notSure: any = 4;
notSure = "maybe a string instead";


어떤 타입이든 할당할 수 있는 타입. TypeScript의 타입 검사를 무시하게 되므로 주의해서 사용해야 함.

9. Void

typescript
function warnUser(): void {
  console.log("This is my warning message");
}


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



## 고급 타입

10. 유니온 (Union)

typescript
let unionType: string | number;


여러 타입 중 하나일 수 있음을 나타냄. '또는'의 의미를 가짐.

11. 인터섹션 (Intersection)

typescript
type Employee = Person & { employeeId: number };


여러 타입을 결합하여 새로운 타입을 만듦. '그리고'의 의미를 가짐.

&&와 비슷한 개념으로, a이면서 동시에 b인 타입임

12. 함수 (Function)

let myFunc: (arg1: number, arg2: number) => number;
myFunc = function(x, y) {
  return x + y;
}
myFunc(1, 2); // 3

let noneFunc: () => void;
noneFunc = function () {
  console.log('hihi');
};


함수의 매개변수 타입과 반환 타입을 정의.


그 외


1. 읽기 전용 (readonly)
- 배열이나 객체의 속성을 변경할 수 없게 만듦.

typescript
  let arrA: readonly number[] = [1, 2, 3, 4];
  let arrB: ReadonlyArray<number> = [2, 4, 6, 8];


2. 튜플 (Tuple)
- 각 요소의 타입이 정해진 배열을 만들 때 유용 .

typescript
  let tuple: [string, number] = ['a', 1];
  let userA: [number, string, boolean] = [1234, 'juyoung', true];


3. 열거형 (enum)
- 관련된 상수들을 그룹화하여 가독성과 유지보수성을 높임.

typescript
  enum Week { Sun, Mon, Tue, Wed, Thu, Fri, Sat }
  enum Color { Red = 'red', Green = 'green', Blue = 'blue' }


  4. 객체 (object)
- 객체의 구체적인 형태를 지정하지 않고 일반적인 객체 타입을 나타낼 때 사용.

typescript
  let obj: object = {};
  let arr: object = [];
  let func: object = function () {};


5. 알 수 없는 타입 (unknown)
- `any`보다 안전한 타입으로, 사용 전 타입 체크를 강제.

typescript
  let u: unknown = 123;
  let test2: number = u as number; // 타입 단언 필요


 6. Never
- 절대 발생하지 않는 값의 타입.

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

 


타입 vs 인터페이스

 

주요 차이점

1. 확장성 

= 인터페이스 -> 동일한 이름으로 여러 번 선언 가능, 속성 추가 가능

= 타입 -> 한번 선언 후 재선언 불가

 

2. 복잡한 타입 표현

= 인터페이스 -> 주로 객체 형태의 타입 정의에 사용

= 타입 -> 유니온 타입, 튜플 등 복잡한 타입 표현

 

정리

인터페이스 -> 객체 형태 정의 및 확장 가능성 필요할 때

타입 -> 복잡한 타입 표현 필요할 때

 


타입 스크립트는 구조적 타입 시스템 사용

 

핵심 개념

1. 타입은 값의 형태와 구조에 따라 결정됨

2. 같은 구조를 가진 두 개체는 동일한 타입으로 간주됨

interface Person { name: string; age: number; }
let p1: Person = { name: "Alice", age: 25 };
let p2 = { name: "Bob", age: 30 };
p1 = p2; // 성공: p2는 Person과 동일한 구조를 가짐

타입 어노테이션 -> 개발자가 직접 변수, 함수 등의 타입을 명시적으로 지정하는 방법

타입 추론 -> 타입스크립트 컴파일러가 코드의 문맥을 통해 자동으로 타입을 추론하는 기능

 

타입 어노테이션이 필요한 경우

1. 함수가 any 타입을 반환하고 이를 명확히 해야할 때

2. 변수를 선언한 후 다른 라인에서 초기화 할 때

3. 추론할 수 없는 타입을 변수가 가지게 하려 할 때

// 1. any 타입 반환 명확화
const json = '{"a": 1, "b": 2}';
const object: { a: number; b: number } = JSON.parse(json);

// 2. 나중에 초기화되는 변수
let foundColor: boolean;
for (let color of colors) {
    if (color === 'blue') foundColor = true;
}

// 3. 추론할 수 없는 타입
let numberAboveZero: boolean | number = false;
for (let num of numbers) {
    if (num > 0) numberAboveZero = num;
}

제네릭

-> 타입을 마치 함수의 파라미터처럼 사용하는 것

-> 재사용 가능한 컴포넌트를 만들어 다양한 타입에서 작동할 수 있게 함

 

 

- 기존 방식

function printStrings(arr: string[]): void {
  for (let i = 0; i < arr.length; i++) {
    console.log(arr[i]);
  }
}

function printNumbers(arr: number[]): void {
  for (let i = 0; i < arr.length; i++) {
    console.log(arr[i]);
  }
}

타입별로 함수 생성

 

- 제네릭 사용

function printAnything<T>(arr: T[]): void {
  for (let i = 0; i < arr.length; i++) {
    console.log(arr[i]);
  }
}

printAnything(['a', 'b', 'c']); // 문자열 배열
printAnything([1, 2, 3]);      // 숫자 배열

 

제네릭 타입도 자동으로 추론 가능


유틸리티 타입

= 기존 타입을 변환해 새로운 타입을 만드는 내장 타입 도구



1. Pick<T, K>: T에서 프로퍼티 K의 집합을 선택해 새 타입을 만듦.

typescript
   type TodoPreview = Pick<Todo, 'title' | 'completed'>;



2. Omit<T, K>: T에서 K를 제외한 프로퍼티로 새 타입을 만듦.

typescript
   type TodoPreview = Omit<Todo, 'description'>;



3. Exclude<T, U>: .

typescript
   type T0 = Exclude<"a" | "b" | "c", "a">;  // "b" | "c"



4. Partial<T>: T의 모든 프로퍼티를 선택적으로 만듦. **

typescript
   function updateTodo(todo: Todo, fieldsToUpdate: Partial<Todo>) {
     return { ...todo, ...fieldsToUpdate };
   }



5. Readonly<T>: T의 모든 프로퍼티를 읽기 전용으로 만듦.

typescript
   const todo: Readonly<Todo> = { title: 'Delete inactive users' };



6. Record<K, T>: 키 타입 K와 값 타입 T로 객체 타입을 만듦.

typescript
   const x: Record<Page, PageInfo> = { home: { title: 'home' } };



7. Extract<T, U>: T에서 U에 할당 가능한 타입을 추출.

typescript
   type T0 = Extract<"a" | "b" | "c", "a" | "f">;  // "a"


8. ReturnType<T>: 함수 T의 반환 타입을 구성.

typescript
   type User = ReturnType<typeof getUser>;



9. Parameters<T>: 함수 T의 매개변수 타입을 튜플로 구성.

typescript
   type LogParams = Parameters<typeof log>;



10. Awaited<T>: Promise의 결과 타입을 추론.

typescript
    type FetchDataType = Awaited<ReturnType<typeof fetchData>>;



## 응용 예시

typescript
type Todo = {
  id: number;
  title: string;
  completed: boolean;
}

type TodoId = Pick<Todo, 'id'>
type CreateTodo = Omit<Todo, 'id'>
type ToggleTodo = Omit<Todo, 'title'>
type EditTodo = Partial<Todo> & TodoId;



 

'TIL' 카테고리의 다른 글

테일윈드 설치가 안 되는 줄 알았는데?...  (0) 2025.01.27
리액트 설치가 안 돼요 or 안 열려요 해결 방법  (0) 2025.01.24
24. 08. 19 TIL  (0) 2024.08.19
24. 08. 20 TIL  (0) 2024.08.19
24. 08. 16 TIL  (0) 2024.08.16