소프트웨어 기술(스타트업 위주)
javascript
typescript 정리 입니다. 구체적인 것은 공식문서가 더 구체적입니다. 개괄적인 개념을 설명드립니다.
TypeScript Types and Concepts
1. TypeScript Types
1.1 Primitive Types
1.1.1 Boolean
let isActive: boolean = true
1.1.2 Number
let age: number = 30
1.1.3 String
let name: string = 'John Doe'
1.1.4 Void
function logMessage(): void {
console.log('This function returns nothing')
}
1.1.5 Undefined
let x: undefined = undefined
1.1.6 Null
let y: null = null
1.2 Object Types
1.2.1 Interface
interface Person {
name: string
age: number
}
let user: Person = { name: 'Alice', age: 25 }
1.2.2 Class
class Animal {
name: string
constructor(name: string) {
this.name = name
}
}
1.2.3 Enum
사용 이유
- 코드 가독성 향상
- 타입 안정성 보장
enum Direction {
Up,
Down,
Left,
Right,
}
let dir: Direction = Direction.Up
1.2.4 Array
let numbers: number[] = [1, 2, 3]
1.2.5 Tuple
let userInfo: [string, number] = ['Alice', 25]
1.2.6 Object
let person: { name: string; age: number } = { name: 'Bob', age: 30 }
1.3 Top Types
1.3.1 Unknown
아무 타입이나 받을 수 있지만, 사용 전에는 타입 검사 필수 값을 사용하려면 typeof 로 타입을 검사 해야함.
let value: unknown = 'Hello'
value = 42 // Allowed
1.3.2 Any
let anything: any = 'Hello'
anything = 42 // Allowed
1.4 Bottom Types
1.4.1 Never
: 함수가 절대 반환하지 않을 때 사용 ( 예외발생, 무한반복 )
function error(message: string): never {
throw new Error(message)
}
1.5 Assertions
1.5.1 As [Type]
let someValue: unknown = 'Hello'
let strLength: number = (someValue as string).length
1.5.2 As Any
let valueAny: any = 'Hello'
let len: number = (valueAny as any).length
1.5.3 As Const
let myTuple = ['hello', 42] as const
2. Type Inference
let message = 'Hello World' // Inferred as string
3. Type Compatibility
let num: number = 10
let doubleNum: number = num * 2 // Compatible
4. Combining Types
유니온 빼곤 자주 사용 안해요 저는
4.1 Union Types
let value: string | number
4.2 Intersection Types
interface A {
a: string
}
interface B {
b: number
}
type AB = A & B
4.3 Type Aliases
type ID = string | number
4.4 Keyof Operator
type User = { name: string; age: number }
type UserKeys = keyof User
5. Type Guards / Narrowing
자주 사용하지 않아요 저는
5.1 Instanceof
if (obj instanceof Date) {
console.log(obj.toDateString())
}
5.2 Typeof
if (typeof value === 'string') {
console.log(value.toUpperCase())
}
5.3 Equality
if (x === y) {
console.log('Equal')
}
5.4 Truthiness
if (someVar) {
console.log('Truthy')
}
5.5 Type Predicates
function isString(x: unknown): x is string {
return typeof x === 'string'
}
6. TypeScript Functions
6.1 Typing Functions
function add(a: number, b: number): number {
return a + b
}
6.2 Function Overloading
function greet(person: string): string
function greet(person: string[]): string[]
function greet(person: any): any {
return person
}
7. TypeScript Interfaces
7.1 Types vs Interface
TypeScript에서는 type
과 interface
모두 사용자 정의 타입을 선언할 수 있지만, 목적과 사용 방식에 차이가 있습니다.
공통점
객체의 타입을 정의할 수 있다.
선택적 속성, 읽기 전용 속성, 확장 등 지원한다.
코드 가독성 향상 및 재사용성 증가
차이점 비교
항목 | type | interface |
---|---|---|
용도 | 다양한 타입(객체, 유니언, 튜플 등)에 사용 가능 | 주로 객체 타입 정의에 사용 |
확장 방식 | & (Intersection) 사용 | extends 키워드로 상속 가능 |
선언 병합 | 불가능 | 같은 이름으로 여러 번 선언하면 병합됨 |
유니언/교차 타입 | 지원 (`type A = B | C, B & C`) |
튜플 타입 정의 | 사용 가능 | 불가능 (튜플은 type으로만 정의) |
컴파일 결과 | 거의 동일 (개념적 차이만 있음) | 거의 동일 |
type
예제
type User = {
name: string;
age: number;
};
type Status = "active" | "inactive";
type Point = [number, number];
- interface 예제
interface User {
name: string;
age: number;
}
interface Admin extends User {
role: string;
}
type Alias = { name: string }
interface Interface {
name: string
}
- 언제 무엇을 써야 할까?
상황 | 추천 |
---|---|
유니언, 튜플, 함수 타입 정의 등 | type |
객체 구조 정의 + 확장 + 병합 필요 | interface |
라이브러리 타입 정의 (.d.ts ) | interface 권장 (선언 병합 지원) |
일관성 있게 구조화된 API 타입 작성 시 | interface 또는 type , 스타일 맞추기 |
결론
interface
는 OOP 스타일과 친숙하며, 선언 병합 기능이 강력하다.type
은 자유롭고 유연한 타입 표현에 더 적합하다.팀 또는 프로젝트의 스타일에 따라 일관되게 사용하는 것이 가장 중요하다.
7.2 Extending Interfaces
interface Animal {
name: string
}
interface Dog extends Animal {
breed: string
}
7.3 Interface Declaration
interface Car {
brand: string
speed: number
}
7.4 Hybrid Types
interface Counter {
(start: number): string
reset(): void
}
8. Classes
8.1 Constructor Params
class Person {
constructor(
public name: string,
private age: number,
) {}
}
8.2 Access Modifiers
private 클래스 내부에서만 접근 가능
protected 클래스 + 하위 클래스에서 접근 가능
public 어디서든 접근 가능 (기본값)
class Example {
private x: number
protected y: number
public z: number
}
8.3 Abstract Classes
abstract 클래스는 인스턴스를 직접 생성할 수 없고, 상속받은 클래스에서 반드시 구현해야 할 추상 메서드를 정의합니다.
abstract class Shape {
abstract getArea(): number
}
8.4 Inheritance vs Polymorphism
abstract 클래스는 인스턴스를 직접 생성할 수 없고, 상속받은 클래스에서 반드시 구현해야 할 추상 메서드를 정의합니다.
class Dog extends Animal {
bark() {
console.log('Woof')
}
}
8.5 Method Overriding
class Parent {
greet() {
console.log('Hello')
}
}
class Child extends Parent {
greet() {
console.log('Hi')
}
}
8.6 Constructor Overloading
class Person {
constructor(
public name: string,
public age?: number,
) {}
}
9. Generics
9.1 Generic Types
function identity<T>(arg: T): T {
return arg
}
9.2 Generic Constraints
제약조건 : length 가 정의되어야 합니다.
interface Lengthwise {
length: number;
}
function loggingIdentity<T extends Lengthwise>(arg: T): T {
return arg
}
10. Utility Types
Partial, Pick, Omit, Readonly, Record, Exclude 빼고는 잘 안쓴느 것 같아요 저는 현업에서
10.1 Partial
type PartialUser = Partial<{ name: string; age: number }>
10.2 Pick
type PickUser = Pick<{ name: string; age: number }, 'name'>
10.3 Omit
type OmitUser = Omit<{ name: string; age: number }, 'age'>
10.4 Readonly
type ReadonlyUser = Readonly<{ name: string; age: number }>
10.5 Record
type RecordExample = Record<string, number>
10.6 Exclude
type Excluded = Exclude<'a' | 'b' | 'c', 'a'> // "b" | "c"
10.7 Extract
type Extracted = Extract<'a' | 'b' | 'c', 'a' | 'c'> // "a" | "c"
10.8 Awaited
type AwaitedExample = Awaited<Promise<string>> // string
10.9 Parameters
type FuncParams = Parameters<(name: string, age: number) => void>
10.10 NonNullable
type NonNullableExample = NonNullable<string | null | undefined> // string
10.11 ReturnType
type FuncReturn = ReturnType<() => number> // number
10.12 InstanceType
class Person {
constructor(public name: string) {}
}
type Instance = InstanceType<typeof Person>