TypeScript는 JavaScript의 상위 집합(Superset)으로, 정적 타입을 지원하는 프로그래밍 언어입니다. 주로 JavaScript의 단점을 보완하고, 대규모 프로젝트에서 코드의 안정성과 유지보수성을 높이기 위해 사용됩니다.
목차
- TypeScript의 특징
- TypeScript의 특징
- TypeScript 주요 문법
- TypeScript 환경 설정
- 타입 추론
- 타입 가드(Type Guard)
1. TypeScript의 특징
✅ 정적 타입(Static Typing)
변수, 함수의 매개변수, 반환값 등에 타입을 명시적으로 지정할 수 있습니다.
컴파일 단계에서 타입 오류를 확인할 수 있어 런타임 오류를 줄일 수 있습니다.
let message: string = "Hello, TypeScript!";
message = 123; // ❌ 오류 발생 (string 타입에 숫자를 할당할 수 없음)
✅ 인터페이스(Interface)
객체의 구조를 정의하는 역할을 합니다.
클래스에서 인터페이스를 구현할 수 있습니다.
인터페이스는 컴파일 후 JavaScript 코드에 존재하지 않으며, 타입 체크를 위한 도구로만 사용됩니다.
interface User {
name: string;
age: number;
}
const user: User = { name: "John", age: 30 }; // ✅ 올바른 객체
const invalidUser: User = { name: "Jane" }; // ❌ age 속성이 빠져서 오류 발생
✅ 클래스(Class) 및 접근 제어자
public, private, protected 키워드를 사용하여 접근을 제한할 수 있습니다.
class Person {
private name: string;
constructor(name: string) {
this.name = name;
}
getName(): string {
return this.name;
}
}
const person = new Person("Alice");
console.log(person.getName()); // ✅ 정상 출력
console.log(person.name); // ❌ private 속성 접근 불가
✅ 제네릭(Generics)
다양한 타입을 지원하는 함수나 클래스를 만들 때 사용합니다.
function identity<T>(arg: T): T {
return arg;
}
console.log(identity<string>("Hello")); // "Hello"
console.log(identity<number>(123)); // 123
✅ 타입 추론(Type Inference)
타입을 명시적으로 지정하지 않아도, TypeScript가 자동으로 타입을 추론합니다.
let num = 10; // TypeScript가 num을 number로 추론
num = "hello"; // ❌ 오류 발생
2. TypeScript 주요 문법
2.1 변수와 타입
let isDone: boolean = false;
let count: number = 10;
let userName: string = "Alice";
let arr: number[] = [1, 2, 3]; // 배열
let tuple: [string, number] = ["hello", 10]; // 튜플
let anything: any = "Can be anything"; // 모든 타입 허용
2.2 함수
function add(x: number, y: number): number {
return x + y;
}
2.3 유니온 타입(Union Type)
let value: string | number;
value = "Hello"; // ✅ 가능
value = 123; // ✅ 가능
value = true; // ❌ 오류 발생
2.4 타입 별칭(Type Alias)
type ID = string | number;
let userId: ID = "abc123";
2.5 타입 가드(Type Guards)
function isString(value: any): value is string {
return typeof value === "string";
}
2.6 타입 단언(Type Assertion)
let someValue: any = "This is a string";
let strLength: number = (someValue as string).length;
3. TypeScript 환경 설정
3.1 TypeScript 설치
npm install -g typescript
3.2 tsconfig.json 생성
tsc --init
3.3 TypeScript 코드 실행
tsc index.ts # TypeScript 파일을 JavaScript로 컴파일
node index.js # 실행
타입 추론
TypeScript는 컴파일 시점에 타입을 자동으로 추론합니다. TypeScript의 타입 추론은 개발자가 명시적으로 타입을 작성하지 않은 경우, 코드의 구조와 문맥을 분석하여 가능한 타입을 유추하는 작업입니다. 이는 정적 분석을 통해 이루어지며, 컴파일러가 코드의 문법과 데이터의 흐름을 기반으로 타입을 결정합니다.
### 타입스크립트가 타입을 추론하는 상황
#### 1. 변수 선언 시
변수를 선언하고 초기화할 때, TypeScript는 초기값의 타입을 분석하여 자동으로 타입을 설정합니다.
let x = 10; // 컴파일러가 x의 타입을 number로 추론
x = "hello"; // 오류: string은 number 타입에 할당 불가
#### 2. 함수 반환 타입
TypeScript는 함수 내부의 리턴 값을 보고 반환 타입을 추론합니다.
function add(a: number, b: number) {
return a + b; // 컴파일러가 반환 타입을 number로 추론
}
#### 3. 함수 매개변수와 호출
함수의 매개변수가 명확히 정의되지 않은 경우, 호출 시점에 전달된 값의 타입을 추론합니다.
function greet(name) {
console.log(`Hello, ${name}`);
}
greet("Alice"); // 컴파일러가 name의 타입을 string으로 추론
#### 4. 배열의 타입
배열을 초기화할 때, 컴파일러는 배열에 들어 있는 요소를 기준으로 배열의 타입을 추론합니다.
let numbers = [1, 2, 3]; // 컴파일러가 number[]로 추론
numbers.push("hello"); // 오류: string은 number[] 타입에 추가 불가
#### 5. 객체의 타입
객체를 초기화할 때, 객체의 구조를 분석하여 타입을 자동으로 설정합니다.
let user = { name: "Alice", age: 25 }; // { name: string; age: number }로 추론
user.name = 123; // 오류: number는 string 타입에 할당 불가
#### 6. 제네릭 사용
제네릭을 사용한 경우, 타입은 호출 시 전달된 값에 따라 추론됩니다.
function identity<T>(value: T): T {
return value; // 컴파일러가 T의 타입을 호출 시점에 추론
}
const str = identity("Hello"); // T는 string으로 추론
### 타입 추론의 종류
#### 1. 명시적 추론
TypeScript에서 타입이 명시적으로 지정되지 않았을 때 발생합니다.
let x = 10; // x는 number로 추론
#### 2. 암시적 추론
함수의 매개변수 타입이나 제네릭이 전달된 값을 기준으로 추론합니다.
let sum = (a, b) => a + b; // a와 b는 number로 추론
TypeScript는 다음과 같은 원칙에 따라 `a`와 `b`를 `number`로 추론합니다:
1. `+` 연산자의 일반적인 용도: 숫자 타입이 산술 연산에 사용될 가능성이 높다고 판단.
2. 함수 본문 분석: `a + b`의 결과가 숫자로 보이기 때문에 이를 기준으로 추론.
3. 타입 안정성 유지: TypeScript는 가장 안전한 타입을 추정하려는 경향이 있습니다.
#### 3. 컨텍스트 기반 추론
코드의 문맥에 따라 타입을 추론합니다. 예를 들어 콜백 함수 내에서 자동으로 타입을 결정합니다.
document.addEventListener("click", (event) => {
console.log(event.target); // event는 MouseEvent로 추론
});
### TypeScript 타입 추론의 장점
1. 코드 간소화:
- 타입을 명시적으로 작성하지 않아도 컴파일러가 타입을 결정합니다.
2. 타입 안전성:
- 잘못된 타입이 사용될 경우 컴파일러가 이를 감지하여 오류를 표시합니다.
3. 개발 생산성 향상:
- 적은 코드로 높은 안정성을 유지하며 빠른 개발이 가능합니다.
타입 가드(Type Guard)
타입 가드(Type Guard)는 TypeScript에서 변수가 특정 타입인지 확인하고, 컴파일러에게 해당 타입을 명시적으로 알리는 기술입니다. 이를 통해 코드가 타입 안전하게 동작할 수 있도록 돕습니다.
### 타입 가드란?
타입 가드는 조건문 내에서 타입을 좁히는 도구로 사용됩니다. TypeScript는 타입 가드를 통해 코드의 특정 영역에서 변수가 특정 타입임을 추론합니다. 즉, 타입 체킹과 타입 추론을 강화하기 위한 기법입니다.
### 타입 가드의 종류
#### 1. typeof 타입 가드
`typeof` 연산자를 사용하여 기본 데이터 타입(`string`, `number`, `boolean`, `symbol`)을 확인합니다.
function printId(id: number | string) {
if (typeof id === "string") {
console.log(`ID는 문자열입니다: ${id.toUpperCase()}`);
} else {
console.log(`ID는 숫자입니다: ${id}`);
}
}
- `typeof id === "string"` 조건 내에서 `id`는 `string`으로 추론됩니다.
- `else` 블록에서는 `id`가 `number`로 추론됩니다.
#### 2. instanceof 타입 가드
`instanceof` 연산자를 사용하여 클래스의 인스턴스인지 확인합니다.
class Dog {
bark() {
console.log("멍멍!");
}
}
class Cat {
meow() {
console.log("야옹!");
}
}
function makeSound(animal: Dog | Cat) {
if (animal instanceof Dog) {
animal.bark(); // Dog 타입으로 추론
} else {
animal.meow(); // Cat 타입으로 추론
}
}
- `instanceof`는 객체의 프로토타입 체인을 검사하여 타입을 좁힙니다.
#### 3. in 연산자 타입 가드
객체에 특정 속성이 존재하는지를 확인하는 방식입니다. 객체의 속성을 기반으로 타입을 구분할 수 있습니다.
type Fish = { swim: () => void };
type Bird = { fly: () => void };
function move(animal: Fish | Bird) {
if ("swim" in animal) {
animal.swim(); // Fish 타입으로 추론
} else {
animal.fly(); // Bird 타입으로 추론
}
}
- `"swim" in animal` 조건 내에서 `animal`은 `Fish` 타입으로 좁혀집니다.
#### 4. 사용자 정의 타입 가드
커스텀 함수를 사용하여 조건을 확인하고 특정 타입임을 컴파일러에게 알릴 수 있습니다. 이때 `is` 키워드를 활용하여 타입 정보를 반환합니다.
type Car = { drive: () => void };
type Bike = { pedal: () => void };
function isCar(vehicle: Car | Bike): vehicle is Car {
return (vehicle as Car).drive !== undefined;
}
function operate(vehicle: Car | Bike) {
if (isCar(vehicle)) {
vehicle.drive(); // Car 타입으로 추론
} else {
vehicle.pedal(); // Bike 타입으로 추론
}
}
- `isCar` 함수는 `vehicle`이 `Car` 타입인지 명시적으로 판별합니다.
- 커스텀 타입 가드는 복잡한 타입 확인이 필요한 경우 매우 유용합니다.
#### 5. Discriminated Union (태그된 유니언)
유니언 타입의 각 멤버가 공통의 속성(태그)을 가지는 경우 이를 기반으로 타입을 좁힐 수 있습니다.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "rectangle"; width: number; height: number };
function getArea(shape: Shape): number {
if (shape.kind === "circle") {
return Math.PI * shape.radius 2; // Circle 타입으로 추론
} else {
return shape.width * shape.height; // Rectangle 타입으로 추론
}
}
- `kind`라는 속성은 각 타입에서 고유 값을 가지며, 이를 기준으로 타입이 좁혀집니다.
### 타입 가드의 장점
1. 타입 안전성 강화:
- 조건문 내에서 타입을 명확히 제한하여 런타임 오류를 방지합니다.
2. 타입 추론 개선:
- 조건문 안에서 TypeScript가 타입을 정확히 추론할 수 있도록 도와줍니다.
3. 가독성 향상:
- 코드의 의도를 명확히 전달하며, 타입 체킹을 코드 레벨에서 쉽게 수행할 수 있습니다.
'프로그래밍 > javascript' 카테고리의 다른 글
패키지 관리 도구 정리 및 비교 (npm / npx / yarn / pnpm / bower) (0) | 2025.04.11 |
---|---|
자바스크립트 동등 연산자 (0) | 2025.04.11 |
postman Pre-request script (0) | 2022.10.24 |
Vue.js 환경설정 (0) | 2021.12.09 |
node.js를 이용한 서버 만들기 (0) | 2021.10.08 |