제네릭 인터페이스와 타입 별칭
제네릭 인터페이스와 타입 별칭을 정의하고, 제약 조건과 기본값을 추가하며 각각 어떤 상황에서 유용한지 이해합니다.
제네릭 인터페이스와 타입 별칭은(는) CoddyKit의 무료 TypeScript Academy 강의입니다. 이것은 3개 중 1번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 TypeScript Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. TypeScript Academy 강의에는 총 3개의 강의가 포함되어 있습니다.
소개
목표: 제네릭 인터페이스와 타입 별칭을 사용해 재사용 가능한 형태를 만듭니다. 제약 조건과 기본값을 추가하고 주요 차이점도 알아봅니다.
수업 개요
목표: 구조화된 동시성을 coroutineScope와 함께 적용하고, 예외 전파를 이해하며, 취소 도구를 안전하게 사용합니다.
핵심 아이디어
- coroutineScope는 모든 하위 작업을 기다리며, 하나가 실패하면 형제 작업을 취소합니다.
- launch는 범위 안에서 즉시 실패하고, async는 await()에서 오류를 드러냅니다.
- withTimeout은 제한 시간이 지나면 작업을 취소합니다.
- try/catch로 범위를 감싸 예외를 처리합니다.
제네릭 인터페이스
제네릭 인터페이스는 타입 매개변수를 가집니다. 호출자는 구체적인 타입으로 대체합니다(예: Box<number>).
interface Box<T> {
value: T;
}
const nBox: Box<number> = { value: 42 };
const sBox: Box<string> = { value: "ts" };
console.log(nBox.value, sBox.value);제네릭 타입 별칭
타입 별칭도 제네릭으로 만들 수 있으며 객체, 함수, 유니언 또는 인터섹션을 표현할 수 있습니다.
type Pair<A, B> = { first: A; second: B };
const p1: Pair<number, string> = { first: 1, second: "one" };
const p2: Pair<boolean, boolean> = { first: true, second: false };
console.log(p1, p2);범위의 대기 동작
coroutineScope는 하위 작업이 모두 끝난 후에만 완료되는 하위 범위를 만듭니다.
import kotlinx.coroutines.*
suspend fun doTwoTasks(): Unit = coroutineScope {
// Both run concurrently and the scope waits for them
launch { delay(150); println("Task A done") }
launch { delay(100); println("Task B done") }
// returning Unit implicitly after children complete
}
fun main() = runBlocking {
doTwoTasks()
println("Scope completed")
}실패 시 형제 작업 취소
하위 작업 하나가 예외를 발생시키면 범위가 형제 작업을 취소하고 호출자에게 예외를 다시 전달합니다. 호출 위치에서 try/catch를 사용합니다.
import kotlinx.coroutines.*
suspend fun failingGroup() = coroutineScope {
val a = launch {
try {
repeat(5) { i ->
println("A $i"); delay(60)
}
} finally {
println("A cancelled")
}
}
launch {
delay(120)
throw IllegalStateException("boom") // failure in child
}
a.join() // will be cancelled when sibling fails
}
fun main() = runBlocking {
try {
failingGroup()
} catch (e: Exception) {
println("Caught in caller: ${e.message}")
}
println("Caller continues")
}제약 조건
extends 제약 조건을 추가하면 T가 필요한 멤버(예: id)를 인터페이스 메서드에 제공하도록 할 수 있습니다.
interface Repository<T extends { id: number }> {
getById(id: number): T | undefined;
save(entity: T): void;
}
type User = { id: number; name: string };
const memRepo: Repository<User> = {
store: [] as User[],
getById(id) {
return this.store.find(u => u.id === id);
},
save(u) {
this.store.push(u);
}
} as unknown as Repository<User>;
memRepo.save({ id: 1, name: "Ada" });
console.log(memRepo.getById(1));async와 await 오류
async의 예외는 await()를 호출할 때 발생합니다. try/catch로 처리합니다.
import kotlinx.coroutines.*
suspend fun parseAsync(s: String) = coroutineScope {
val deferred = async {
delay(50)
s.toInt() // may throw NumberFormatException
}
try {
println("Result = ${deferred.await()}") // error appears here
} catch (e: NumberFormatException) {
println("Handled parse error: ${e::class.simpleName}")
}
}
fun main() = runBlocking {
parseAsync("12")
parseAsync("xx")
}기본값과 확장
편리한 사용을 위해 기본 타입 매개변수를 제공하고, 유틸리티로 타입을 확장합니다(예: Readonly<Box<T>>).
interface ApiResponse<T = unknown> {
data: T;
ok: boolean;
}
type ReadonlyBox<T> = Readonly<Box<T>>;
const r1: ApiResponse = { data: "ok", ok: true }; // T defaults to unknown
const r2: ApiResponse<number> = { data: 200, ok: true };
const rb: ReadonlyBox<string> = { value: "fixed" };
// rb.value = "change"; // Error: readonlywithTimeout 취소
withTimeout을 사용하여 작업 시간을 제한합니다. 이 함수는 하위 작업을 취소하고 TimeoutCancellationException을 발생시킵니다.
import kotlinx.coroutines.*
suspend fun slowOp(): Int {
delay(300) // pretend work
return 42
}
fun main() = runBlocking {
try {
val result = withTimeout(150) { slowOp() } // cancels after 150ms
println("Got $result")
} catch (e: TimeoutCancellationException) {
println("Timed out and cancelled")
}
}병합의 차이
인터페이스는 선언 병합을 지원합니다. 타입 별칭은 병합할 수 없으며, 중복된 이름은 오류입니다.
interface Settings { theme: string }
interface Settings { lang: string }
// Merged: Settings has { theme: string; lang: string }
const s: Settings = { theme: "dark", lang: "en" };
// type Settings = { foo: string };
// Error: Duplicate identifier 'Settings' for type aliases (no merging)구조화된 동시성의 실패 규칙
인터페이스와 타입 확인
빠른 확인: 제네릭 인터페이스와 타입 별칭에 대한 설명 중 TRUE인 것은 무엇입니까?
요약
요약: 재사용 가능한 형태를 모델링할 때 제네릭 인터페이스와 타입 별칭을 사용합니다. 제약 조건과 기본값을 추가하고, 인터페이스만 병합된다는 점을 기억합니다.
요약
요약: 작업을 그룹화하려면 coroutineScope를 사용하고, 실패한 하위 작업은 형제 작업을 취소합니다. try/catch로 오류를 처리하고, await()에서 async 실패를 드러내며, withTimeout으로 오래 걸리는 작업을 취소합니다.
자주 묻는 질문
“제네릭 인터페이스와 타입 별칭” 강의는 무료인가요?
네 — “제네릭 인터페이스와 타입 별칭” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 TypeScript Academy 강의 전체를 잠금 해제할 수 있습니다. TypeScript Academy 강의에는 총 3개의 강의가 포함되어 있습니다.
“제네릭 인터페이스와 타입 별칭”에서 뭘 배우나요?
제네릭 인터페이스와 타입 별칭을 정의하고, 제약 조건과 기본값을 추가하며 각각 어떤 상황에서 유용한지 이해합니다. 브라우저에서 직접 실행하는 실습 코드로 TypeScript Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
TypeScript Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 TypeScript Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 3개 중 1번째 강의입니다.
“제네릭 인터페이스와 타입 별칭” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 TypeScript Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 TypeScript Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 제네릭 인터페이스와 타입 별칭
- 조건부 타입(입문)과 유니온에 대한 분배
- 데이터 모델을 위한 재사용 가능한 패턴