TypeScript 기초 · 타입 선언 · 인터페이스와 타입 · 클래스
JavaScript의 타입 오류를 컴파일 시점에 잡아주는 TypeScript의 가치, tsc 컴파일러, tsconfig.json 설정, 그리고 기본 타입(string/number/boolean/any/unknown/배열/튜플)을 익힙니다. 변수와 함수의 타입 선언, 선택적/기본값 매개변수, void와 never의 차이, 타입 추론, 그리고 타입 단언(as)까지 익힙니다. interface와 type alias의 차이, 선택적 프로퍼티, readonly, 인터페이스 확장(extends), 유니온(|)과 교차(&) 타입, 인덱스 시그니처를 익힙니다. TypeScript 클래스 — 매개변수 프로퍼티 축약, 접근 제어자(public/private/protected/readonly), 상속(extends/super), 추상 클래스(abstract), 인터페이스 구현(implements)을 익힙니다.
이 강의에서 배우는 것
- 1TS가 해결하는 JS의 3가지 한계를 안다
- 2tsc로 .ts → .js 컴파일을 수행한다
- 3tsconfig.json 의 주요 옵션(target/strict/outDir)을 안다
- 4기본 타입과 any vs unknown 의 차이를 구분한다
- 5함수의 매개변수·반환 타입을 명시한다
- 6?와 = 로 선택적/기본값 매개변수를 정의한다
- 7void와 never의 차이를 안다
- 8타입 추론을 활용해 불필요한 명시를 줄인다
- 9as 단언이 필요한 상황과 위험을 안다
- 10interface와 type 의 차이와 선택 기준을 안다
- 11선택적(?)과 readonly 프로퍼티를 사용한다
- 12extends로 인터페이스를 확장한다
- 13유니온(|)과 교차(&) 타입을 작성한다
- 14인덱스 시그니처로 동적 키를 표현한다
- 15constructor와 매개변수 프로퍼티 축약을 사용한다
- 16public/private/protected/readonly를 적절히 적용한다
- 17extends와 super로 상속한다
- 18abstract로 추상 클래스를 만든다
- 19implements로 인터페이스를 구현한다
TypeScript 기초
JavaScript의 타입 오류를 컴파일 시점에 잡아주는 TypeScript의 가치, tsc 컴파일러, tsconfig.json 설정, 그리고 기본 타입(string/number/boolean/any/unknown/배열/튜플)을 익힙니다.
1. TypeScript가 필요한 이유
JS의 한계 — 타입 오류는 런타임에만 발견
function add(a, b) { return a + b; }
add('10', 20); // '1020' — 의도와 다른 결과, 오류도 아님!
const user = { name: '홍길동', age: 30 };
console.log(user.email.toUpperCase()); // 런타임 오류!TypeScript로 해결
function add(a: number, b: number): number {
return a + b;
}
add('10', 20); // 컴파일 오류: 'string'은 'number'에 할당 불가
const user = { name: '홍길동', age: 30 };
console.log(user.email); // 컴파일 오류: 'email' 없음2. 설치 & 컴파일
npm install -g typescript # 전역
tsc --version
npm install --save-dev typescript # 프로젝트 로컬
npx tsc --version
tsc hello.ts # .ts → .js 컴파일
node hello.js
tsc --watch hello.ts # 감시 모드
tsc # tsconfig.json 있으면 그냥3. tsconfig.json
tsc --init # tsconfig.json 자동 생성{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}4. TS Playground
https://www.typescriptlang.org/play — 브라우저에서 바로 TypeScript 실험 가능. 설치 없이 코드와 컴파일 결과 확인.
5. 기본 타입
let name: string = '홍길동';
let age: number = 30;
let isActive: boolean = true;
// any: 타입 검사 건너뜀 (사용 자제)
let anything: any = '문자열';
anything = 42;
// unknown: any보다 안전 — 사용 전 타입 확인 필요
let input: unknown = '입력값';
if (typeof input === 'string') {
input.toUpperCase();
}
// 배열
let numbers: number[] = [1, 2, 3];
let mixed: (string | number)[] = ['a', 1, 'b', 2];
// 튜플 — 길이/타입 고정
let point: [number, number] = [10, 20];
let entry: [string, number] = ['나이', 25];
// null / undefined
let nullable: string | null = null;
let optional: number | undefined = undefined;타입 선언
변수와 함수의 타입 선언, 선택적/기본값 매개변수, void와 never의 차이, 타입 추론, 그리고 타입 단언(as)까지 익힙니다.
1. 변수 타입 선언
let name: string = '홍길동';
let age: number = 30;
// 타입 추론 — 초기값으로 자동 결정
let city = '서울'; // string
let score = 100; // number2. 함수 매개변수와 반환 타입
function add(a: number, b: number): number {
return a + b;
}
const multiply = (a: number, b: number): number => a * b;3. 선택적 매개변수 (?)
function greet(name: string, title?: string): string {
if (title) return `안녕하세요, ${title} ${name}님!`;
return `안녕하세요, ${name}님!`;
}
greet('홍길동'); // OK
greet('홍길동', '선생님'); // OK4. 기본값 매개변수
function createUser(name: string, role: string = 'user'): object {
return { name, role };
}
createUser('홍길동'); // { name: '홍길동', role: 'user' }
createUser('관리자', 'admin');5. void와 never
// void: 반환값 없음
function logMessage(msg: string): void {
console.log(msg);
}
// never: 절대 반환 안 함 (오류 던지기, 무한 루프)
function throwError(message: string): never {
throw new Error(message);
}
function infiniteLoop(): never {
while (true) {}
}6. 타입 추론
let x = 10; // number
let y = 'hello'; // string
let arr = [1, 2, 3]; // number[]
function double(n: number) {
return n * 2; // 반환: number 추론
}7. 타입 단언 (as)
// HTML 요소 접근
const input = document.getElementById('username') as HTMLInputElement;
input.value = '홍길동';
// 다른 표현 (JSX 불가)
const input2 = <HTMLInputElement>document.getElementById('username');
// unknown 단언
let data: unknown = '문자열';
const str = data as string;타입 단언은 실제 타입을 바꾸지 않습니다 — 오남용 주의!
인터페이스와 타입
interface와 type alias의 차이, 선택적 프로퍼티, readonly, 인터페이스 확장(extends), 유니온(|)과 교차(&) 타입, 인덱스 시그니처를 익힙니다.
1. interface vs type alias
// interface
interface User {
id: number;
name: string;
email: string;
}
// type alias
type User = {
id: number;
name: string;
email: string;
};| 기능 | interface | type |
|---|---|---|
| 선언 병합 | O | X |
| 확장 | extends | & (교차) |
| 유니온 정의 | X | O |
| 원시 타입 별칭 | X | O |
관례: 객체 형태는 interface, 유니온/교차/원시 별칭은 type.
2. 선택적 프로퍼티 (?)
interface Product {
id: number;
name: string;
price: number;
description?: string; // 있어도, 없어도 됨
imageUrl?: string;
}
const product: Product = {
id: 1,
name: '노트북',
price: 1500000,
};3. readonly
interface Config {
readonly apiKey: string;
readonly baseUrl: string;
timeout: number;
}
const config: Config = { apiKey: 'abc', baseUrl: '...', timeout: 3000 };
config.timeout = 5000; // OK
config.apiKey = 'xyz'; // 오류: readonly4. 인터페이스 확장 (extends)
interface Animal {
name: string;
age: number;
}
interface Dog extends Animal {
breed: string;
}
const dog: Dog = { name: '멍멍이', age: 3, breed: '진돗개' };5. 유니온 (|)
type ID = string | number;
type Status = 'pending' | 'active' | 'inactive';
let userId: ID = 123;
userId = 'user_abc'; // OK
let status: Status = 'active';
status = 'deleted'; // 오류: Status에 없음6. 교차 타입 (&)
type Admin = User & {
permissions: string[];
level: number;
};
const admin: Admin = {
id: 1, name: '관리자', email: 'admin@…',
permissions: ['read', 'write'],
level: 5,
};7. 인덱스 시그니처
interface StringMap {
[key: string]: string;
}
const translations: StringMap = {
hello: '안녕하세요',
goodbye: '안녕히 가세요',
};
translations.welcome = '환영합니다';클래스
TypeScript 클래스 — 매개변수 프로퍼티 축약, 접근 제어자(public/private/protected/readonly), 상속(extends/super), 추상 클래스(abstract), 인터페이스 구현(implements)을 익힙니다.
1. 클래스 선언
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
greet(): string {
return `안녕하세요, 저는 ${this.name}입니다.`;
}
}매개변수 프로퍼티 (축약)
class Person {
// constructor 매개변수에 접근 제어자 → 프로퍼티 자동 선언/할당
constructor(
public name: string,
private age: number,
) {}
}2. 접근 제어자
| 제어자 | 접근 범위 |
|---|---|
| public | 어디서나 (기본값) |
| private | 클래스 내부만 |
| protected | 클래스 + 자식 클래스 |
| readonly | 초기화 후 변경 불가 |
class BankAccount {
private balance: number;
readonly accountId: string;
constructor(initialBalance: number) {
this.balance = initialBalance;
this.accountId = `ACC-${Date.now()}`;
}
getBalance(): number { return this.balance; }
deposit(amount: number): void {
if (amount <= 0) throw new Error('금액은 양수여야 합니다.');
this.balance += amount;
}
}3. 상속 (extends)
class Animal {
constructor(public name: string) {}
speak(): string { return `${this.name}이(가) 소리를 냅니다.`; }
}
class Dog extends Animal {
constructor(name: string, public breed: string) {
super(name); // 부모 constructor 호출 필수
}
// 오버라이드
speak(): string { return `${this.name}이(가) 멍멍 짖습니다!`; }
fetch(): string { return `${this.name}이(가) 공을 가져옵니다.`; }
}4. 추상 클래스 (abstract)
abstract class Shape {
abstract area(): number;
abstract perimeter(): number;
describe(): string {
return `넓이: ${this.area()}, 둘레: ${this.perimeter()}`;
}
}
class Circle extends Shape {
constructor(private radius: number) { super(); }
area(): number { return Math.PI * this.radius ** 2; }
perimeter(): number { return 2 * Math.PI * this.radius; }
}
// new Shape(); // 오류: 추상 클래스
const circle = new Circle(5);5. 인터페이스 구현 (implements)
interface Flyable {
fly(): string;
maxAltitude: number;
}
interface Swimmable {
swim(): string;
}
class Duck implements Flyable, Swimmable {
maxAltitude = 100;
fly(): string { return '오리가 납니다!'; }
swim(): string { return '오리가 헤엄칩니다!'; }
}댓글 0
아직 댓글이 없습니다. 첫 댓글을 남겨 주세요.
댓글은 회원만 쓸 수 있습니다.
광고·욕설·비방·개인정보·불법 내용이 담긴 댓글은 숨기거나 지웁니다. 댓글은 닉네임과 함께 공개됩니다. 개인정보처리방침