| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
- 유레카 부트캠프
- 소수
- 브루트포스
- Do it! 자료구조와 함께 배우는 알고리즘 입문
- 자바
- 프론트엔드
- 웹시큐리티
- 부트캠프후기
- 멀티캠퍼스IT부트캠프티
- 코딩
- 재귀
- LG유플러스 유레카 프론트엔드
- 애자일
- 스레드
- 시간 복잡도
- 알고리즘
- LG유플러스 유레카 3기 프론트엔드
- 프로세스
- 정렬
- 별찍기10
- Java
- LG유플러스 유레카 프론트엔드 개발자
- zod
- 프론트엔드 비대면반
- 백준
- tanstack query
- 2775번 문제
- LG유플러스 유레카 부트캠프
- 멀티캠퍼스IT부트캠프
- git branch 협업
- Today
- Total
개발 일기
20250904 TypeScript 본문
타입스크립트의 Class
접근 제어자
타입스크립트는 클래스 멤버의 접근 수준을 제어할 수 있는 접근 제어자를 제공한다.
- public : (기본값) 어디에서나 클래스 멤버에 접근할 수 있다.
- private : 클래스 내부에서만 클래스 멤버에 대한 접근을 허용한다.
- protected : 클래스와 상속받은 클래스에서만 접근 가능하다. (Java에서 더 자세히 다룰 예정)
class Person {
private name: string;
public constructor(name: string) {
this.name = name;
}
public getName(): string {
return this.name;
}
}
const person = new Person("Jane");
console.log(person.getName()); // Jane 출력
console.log(person.name); // 오류: name은 private 멤버이므로 클래스 외부에서 접근 불가
readonly
class Person {
private readonly name: string;
public constructor(name: string) {
this.name = name;
}
setName(newName: string) {
// this.name = newName; // 오류 발생
}
}
생성자에서 초기화할 때만 값을 할당 가능하고 그 이후에는 클래스 내부든 외부든 수정할 수 없게 된다.
implements 상속 구현
interface Shape {
getArea: () => number;
}
class Rectangle implements Shape {
public constructor(protected readonly width: number, protected readonly height: number) {}
public getArea(): number {
return this.width * this.height;
}
}
interface는 implements 키워드를 통해 클래스가 따라야 하는 유형을 정의하는 데 사용할 수 있다.
extends 상속 구현
interface Shape {
getArea: () => number;
}
class Rectangle implements Shape {
public constructor(protected readonly width: number, protected readonly height: number) {}
public getArea(): number {
return this.width * this.height;
}
}
class Square extends Rectangle {
public constructor(width: number) {
super(width, width); // 부모 생성자를 호출. 양 변이 같음으로 width, width
}
// getArea gets inherited from Rectangle
}
Square는 Rectangle에서 정의된 getArea() 메서드를 그대로 상속받아 사용할 수 있다. super()는 부모 클래스의 생성자나 메서드를 호출할 때 사용된다.
override 키워드
interface Shape {
getArea: () => number;
}
class Rectangle implements Shape {
public constructor(protected readonly width: number, protected readonly height: number) {}
public getArea(): number {
return this.width * this.height;
}
}
class Square extends Rectangle {
public constructor(width: number) {
super(width, width);
}
public getAre(): string {
console.log(`넓이는 ${this.width * this.width}입니다.`);
}
const squ = new Square(5);
squ.getArea(); // Rectangle 클래스의 getArea()가 호출됨.
override는 위처럼 원치않는 메서드의 호출이 되는 상황을 방지하는 데 사용된다.
사용 예시
interface Shape {
getArea: () => number;
}
class Rectangle implements Shape {
public constructor(protected readonly width: number, protected readonly height: number) {}
public getArea(): number {
return this.width * this.height;
}
}
class Square extends Rectangle {
public constructor(width: number) {
super(width, width);
}
public override getArea(): string {
return `넓이는 ${this.width * this.width} 입니다.`;
}
}
abstract 키워드
abstract는 모든 멤버를 구현하지 않고도 다른 클래스의 기반 클래스로 사용될 수 있도록 작성할 수 있게 해준다.
abstract class Polygon {
public abstract getArea(): number;
public toString(): string {
return `Polygon[area=${this.getArea()}]`;
}
}
class Rectangle extends Polygon {
public constructor(protected readonly width: number, protected readonly height: number) {
super();
}
public getArea(): number {
return this.width * this.height;
}
}
멤버가 abstract이면 클래스에도 붙여주어야 된다. 미완성된 메서드는 상속받아 호출해도 실행되지 않고 구체화해주어야 실행된다.
타입스크립트 제네릭
제네릭은 타입 변수를 사용하여 클래스, 함수, 타입 별칭 등을 정의할 수 있게 해준다. 이를 통해 타입을 명시적으로 지정하지 않고도 다양한 타입에 대해 안전하게 동작하는 코드를 작성할 수 있다.
함수에서 제네릭 사용
function createPair<S, T>(v1: S, v2: T): [S, T] {
return [v1, v2];
}
S와 T는 타입 변수로 함수 호출 시 실제 타입으로 대체된다.
사용 예시
console.log(createPair<string, number>('hello', 42)); // ['hello', 42]
메서드명 뒤에 < > 사이에 타입을 명시해서 사용한다.
클래스에서 제네릭 사용
class NamedValue<T> {
private _value: T | undefined;
constructor(private name: string) {}
public setValue(value: T) {
this._value = value;
}
public getValue(): T | undefined {
return this._value;
}
public toString(): string {
return `${this.name}: ${this._value}`;
}
}
let value = new NamedValue<number>('myNumber');
value.setValue(10);
console.log(value.toString()); // myNumber: 10
함수에서 사용했던 것처럼 동일하게 사용된다. 만약 class NameValue<T = string> {} 으로 작성하게 되면 인스턴스 생성 시 타입을 명시하지 않으면 기본값으로 string이 사용된다.
Type Aliases
type Wrapped<T> = { value: T };
const wrappedValue: Wrapped<number> = { value: 10 };
type 키워드의 제네릭을 사용하면 재사용성이 더 높은 유형을 만들 수 있다.
타입스크립트 Utility 타입
1. Partial
객체 타입의 모든 속성을 선택적으로 만든다.
interface Point { x: number; y: number; }
let pointPart: Partial<Point> = {}; // x와 y는 선택적
pointPart.x = 10;
2. Required
객체 타입의 모든 속성을 필수로 만든다.
interface Car {
make: string;
model: string;
mileage?: number;
}
let myCar: Required<Car> = {
make: 'Ford',
model: 'Focus',
mileage: 12000 // 마일리지도 무조건 선언해야된다.
};
3. Record
특정 키 타입과 값 타입을 갖는 객체 타입을 정의한다.
const nameAgeMap: Record<string, number> = {
'Alice': 21,
'Bob': 25
};
4. Omit
객체 타입에서 특정 키를 제외한 타입을 생성한다.
interface Person {
name: string;
age: number;
location?: string;
}
const bob: Omit<Person, 'age' | 'location'> = {
name: 'Bob'
};
5. Pick
객체 타입에서 특정 키만 선택한 타입을 생성한다.
interface Person {
name: string;
age: number;
location?: string;
}
const bob: Pick<Person, 'name'> = {
name: 'Bob'
// name키만 선택했기 때문에 age와 location은 제외
};
6. Exclude
유니온 타입에서 명시한 타입을 제외한 타입을 생성한다.
type Primitive = string | number | boolean
const value: Exclude<Primitive, string> = true; // string을 제외한 boolean, number만 가능
7. ReturnType
함수 유형의 반환 유형을 추출한다.
type PointGenerator = () => { x: number; y: number; };
const point: ReturnType<PointGenerator> = {
x: 10,
y: 20
};
8. Parameters
함수 유형의 매개변수 유형을 배열로 추출한다.
type PointPrinter = (p: { x: number; y: number; }) => void;
const point: Parameters<PointPrinter>[0] = {
x: 10,
y: 20
};
타입스크립트 keyof
keyof란?
keyof는 객체 타입에서 키 이름 들만 골라내어 문자열 또는 숫자 리터럴 Union 타입으로 만들어주는 타입 연산자이다.
사용 예제
interface Person {
name: string;
age: number;
}
// `keyof Person`는 name과 age 유니온 타입을 만들고 다른 문자열은 들어올 수 없다.
function printPersonProperty(person: Person, property: keyof Person) {
console.log(`Printing person property ${property}: "${person[property]}"`);
}
let person = {
name: "Max",
age: 27
};
printPersonProperty(person, "name");
객체 타입에 인덱스 시그니처에도 사용 가능하다.
객체 타입에 인덱스 시그니처가 있을 경우 keyof는 해당 키 타입 전체를 반환한다.
type StringMap = { [key: string]: unknown };
type K = keyof StringMap; // type K = string
'TIL' 카테고리의 다른 글
| 20250908 OOP 3대 concept (1) | 2025.09.08 |
|---|---|
| 20250907 자바스크립트 V8 엔진 (0) | 2025.09.07 |
| 20250903 TypeScript (0) | 2025.09.04 |
| 20250902 JavaScript 비동기 (0) | 2025.09.02 |
| 20250901 JavaScript 화살표 함수와 this (0) | 2025.09.01 |