TypeScript
타입 추론 Type Inference
타입 추론이란?
컴파일러가 변수나 표현식의 타입을 자동으로 결정하는 과정을 말한다.
명시적으로 타입을 지정하지 않아도, 컴파일러는 코드의 문맥과 값을 기반으로 타입을 추론한다.
이를 통해 타입 선언에 신경 쓰기보다 로직 구현에 집중할 수 있게 도와준다.
let myNumber = 7; // number 타입으로 추론
let myString = 'July'; // string 타입으로 추론
let myBool = true; // boolean 타입으로 추론
function getName(user: { name: string }) {
return user.name;
} // 반환 값을 string 타입으로 추론
타입 단언 Type Assertion
타입 단언이란?
개발자가 직접 컴파일러에게 변수나 객체의 타입에 대해 알리는 방식으로,
개발자가 해당 타입에 대해 더 많은 정보를 가지고 있는 경우 사용할 수 있다.
const someValue: unKnown = 'hello';
someValue.length; // error
const length_1 = (someValue as string).length; // 5
const length_2 = <string>someValue.length; // 5
// HTMLElement | null
const input = document.getElementById('myInput') as HTMLInputElement;
if (input) {
console.log(input.value);
}
클래스 Class
클래스는 객체를 생성하기 위한 템플릿 역할을 하며,
생성자, 속성, 메서드로 구성되어 있다.
class Country {
// 속성
private code: number;
name: string;
capital string
// 생성자
constructor(code: number, name: string, capital: string) {
this.code = code;
this.name = name;
this.capital = capital
}
//메서드
displayInfo(): string {
return `${this.name} (Code: ${this.code}). Capital: ${this.capital}`
}
}
상속
클래스는 또 다른 클래스의 속성과 메서드를 extends라는 키워드를 통해 상속받아 사용할 수 있다.
class Continent {
continentName: string;
constructor(name: string) {
this.continentName = name;
}
getContinentName() {
return this.continentName;
}
}
class Country extends Continent{
// 속성
name: string;
capital string
// 생성자
constructor(continentName:string ,code: number, name: string, capital: string) {
super(continentName) // 상위 클래스의 생성자 호출
this.name = name;
this.capital = capital
}
//메서드
getInfo() {
return `${this.name}, ${this.capital}, ${this.getContinentName()} `
}
}
let country = new Country('Asia', 'South Korea', 'Seoul')
console.log(country.getInfo()) // South Korea, Seoul, Asia
접근제어자
클래스 내 속성이나 메서드에 대해 접근 가능 범위를 설정하는 키워드
public(기본값)
클래스 내부 및 외부에서 접근 가능privateor#
해당 클래스 내부에서만 접근 가능하며,
서브 클래스 및 외부에서는 접근 불가protected
해당 클래스 및 서브 클래스에서 접근 가능하며,
외부에서는 접근 불가
interface
인터페이스는 클래스가 따라야 할 구조를 정의하는데 사용된다.
클래스는 implements 키워드를 사용하여 해당 인터페이스를 구현할 수 있다.
이 과정에서 public한 속성과 메서드만 인터페이스로 정의할 수 있다.
interface ContinentInterface {
getContinentName(): string;
}
class Continent implements ContinentInterface {
protected continentName: string;
constructor(name: string) {
this.continentName = name;
}
getContinentName() {
return this.continentName;
}
}
클래스는 상속과 인터페이스 구현을 모두 사용할 수 있는데,
이때 상속을 먼저 작성하고, 인터페이스 구현은 그 뒤에 작성한다.
abstract class
추상 클래스는 다른 클래스의 상속 대상이 되는 클래스로,
추상 클래스에서 직접적으로 인스턴스를 생성할 수 없고, 추상 클래스를 상속한 클래스에서 인스턴스를 생성할 수 있다.
추상 클래스에서는 해당 클래스를 상속할 클래스의 속성 및 메서드의 모양을 정의하고,
구체화되지 않은 메서드는 abstract 키워드를 사용하여 선언하며, 서브 클래스에서 반드시 구현해야 한다.
abstract class Shape {
constructor(public color: string) {}
abstract area(): number; // 서브 클래스에서 구현해야 함
describe(): string {
return `This shape is ${this.color}.`;
}
}
class Circle extends Shape {
constructor(color: string, private radius: number) {
super(color);
}
area(): number {
return Math.PI * this.radius ** 2;
}
}
const circle = new Circle('red', 5);
console.log(circle.describe()); // "This shape is red."
console.log(circle.area()); // 78.53981633974483
제네릭 Generics
제네릭은 함수, 인터페이스, 클래스 등에 타입을 매개변수처럼 사용할 수 있게 하여,
다양한 타입의 데이터를 처리할 수 있는 패턴을 제공한다.
함수에서의 사용
function identity<T>(value: T): T {
return value;
}
// 호출 시 타입 지정 (명시적으로 지정하거나 추론 가능)
console.log(identity<string>('hello')); // "hello"
console.log(identity<number>(123)); // 123
인터페이스에서의 사용
interface Box<T> {
value: T;
}
const stringBox: Box<string> = { value: 'Hello' };
const numberBox: Box<number> = { value: 42 };
console.log(stringBox.value); // "Hello"
console.log(numberBox.value); // 42
클래스에서의 사용
class DataStore<T> {
private data: T[] = [];
addItem(item: T): void {
this.data.push(item);
}
getItems(): T[] {
return this.data;
}
}
const stringStore = new DataStore<string>();
stringStore.addItem('Item1');
stringStore.addItem('Item2');
console.log(stringStore.getItems()); // ["Item1", "Item2"]
const numberStore = new DataStore<number>();
numberStore.addItem(10);
numberStore.addItem(20);
console.log(numberStore.getItems()); // [10, 20]
제네릭 타입 제한
extends 키워드를 통해 타입의 제한을 설정할 수 있다.
// 제네릭 타입이 string 또는 number로 제한
function printId<T extends string | number>(id: T): void {
console.log(`ID: ${id}`);
}
printId(123); // "ID: 123"
printId('abc'); // "ID: abc"
printId(true); // true는 string도 아니고 number도 아니기 때문에 error 발생
두 개 이상의 제네릭 타입
interface Entry<K, V> {
key: K;
value: V;
}
let entry: Entry<string, number>= {
key: 'age'
value: 30
}'Notes > TypeScript' 카테고리의 다른 글
| TypeScript Chapter. 5 (1) | 2024.12.09 |
|---|---|
| TypeScript Chapter. 4 (1) | 2024.12.08 |
| TypeScript Chapter. 2 (1) | 2024.12.07 |
| TypeScript Chapter. 1 (1) | 2024.12.05 |