본문 바로가기

TypeScript

[TypeScript 강의노트] - 고급타입

반응형

1. Intersection

2. Union Types

2. 타입 별칭 type-alias

3. 인덱스 타입

 

 

1. Intersection

- 여러 타입을 하나로 합쳐진 타입

 

interface User {
    name: string;
}

interface Action {
    do(): void;
}

//Intersection - 여러타입을 하나로 합쳐진 타입
function createUserAcion(u: User, a: Action): User & Action {
    return { ...u, ...a };
}

const u = createUserAcion({ name: "jay" }, { do() {} });
u.do; //가능
u.name; //가능

 

 

2. Union Types

- or 을 사용해서 두 개의 타입 사용할 수 있게 한다.

 

1. Union Types - primitive 타입

 

//union type
//x에 string 또는 number 타입이 올 수 있다.
function compare(x: string | number, y: string | number) {
    if (typeof x === "number" && typeof y === "number") { //타입가드
        return x === y ? 0 : x > y ? 1 : -1;
    }
    if (typeof x === "string" && typeof y === "string") {
        return x.localeCompare(y);
    }
    throw Error ("not supported type");
}

 

//함수의 오버로딩으로 같은 타입만 사용할 수 있게 해줌
function compare(x: string, y: string);
function compare(x: number, y: number);

function compare(x: string | number, y: string | number) {
    if (typeof x === "number" && typeof y === "number") {
        return x === y ? 0 : x > y ? 1 : -1;
    }
    if (typeof x === "string" && typeof y === "string") {
        return x.localeCompare(y);
    }
    throw Error("not supported type");
}
const v = compare(1,"D") //error
const v = compare(1,1)
const v = compare("D","D")

 

 

2.  Union Types - primitive 타입이 아닌 interface를 union 타입으로 했을 경우

- v는 두 union 타입의 공통된 멤버에만 접근할 수 있다.

 

2-1) 타입가드 없이 사용

 

interface User {
    name: string;
}

interface Action {
    do(): void;
}

function process(v: User | Action) {
    //타입 확인시 typeof 연산자 사용시, 자바스크립트에서 제공되는 타입밖에 없어서 error 발생
    if (typeof v === "object") {} 
	↓
    //1. 바로 사용시,
    if(v.do) //error
	↓
    //2.v의 타입을 Action으로 고정
    //매번 이런식으로 타입을 정의하면 불편 -> 타입가드 만들기
     if ((<Action>v).do) {
         (<Action>v).do();
     }

 

 

2-2) 타입가드 정의 후 사용

 

interface User {
    name: string;
}

interface Action {
    do(): void;
}

//타입가드
function isAction(v: User | Action): v is Action {
    //타입가드 정의
    return (<Action>v).do !== undefined;
}

function process(v: User | Action) {
    if (isAction(v)) {
    //타입가드로 v는 Action타입으로 인식
        v.do(); 
    } else {
    //알아서 User타입으로 인식
        v.name; 
    }
}

 

 

3. 타입 별칭

- 인터페이스와 비슷하지만, 직접 작성한 타입에 이름을 붙일 수 있다.

- type 키워드를 통해 작성

 

1. intersection 타입으로, union 타입으로,  제네릭으로

 

//1) intersection 타입으로 우선 정의
type UserAction = User & Action;
function createUserAction(): UserAction {
    //intersection 타입 반환 가능
    return {
        name: "",
        do() {},
    };
}

//2) 원시형 타입도 가능, union 타입
type StringOrNumber = string | number;
//3) 타입 별칭은 제네릭도 사용가능
type Arr<T> = T[];
//+ promise 축약해서 간단하게도 가능
type P<T> = Promise<T>;

 

 

2. interface처럼 특정 타입을 정의할 수 있다.

- implements도 가능

 

//4) 인터페이스처럼 특정 타입을 정의할 수 도 있다.
type User22 = {
    name: string;
    login(): boolean;
};

// ↓ 인터페이스가 아닌데 implement도 가능하다
class User333 implements User22 {
    login(): boolean {
        throw new Error("Method not implemented.");
    }
    name: string;
}

 

 

3. 문자 리터럴 타입과 같이 활용 시 유용

- ex) 상태에 따른 타입

 

//5) 문자 리터럴 타입과 같이 활용시 유용하다.
type UserState = "PENDING" | "APPROVED" | "REJECTED"; //union으로 묶어서 상태에 따른 타입
function chechUser(user: User22): UserState {
    if(user.login()){
        return "APPROVED";
}else{
    return "REJECTED"
}

 

 

4. 인덱스 타입

- 속성의 이름이 정해져있지않고 동적으로 처리해야 할 때 사용

 

interface Props {
    [key: string]: string; //인덱스 시그니처 매개변수는 string, number 만 사용가능
}

const p: Props = {
    a: "d",
    b: "e",
    c: 3, //error
    3: "a", //key가 string인 경우, number가 key값이어도 가능, but, key가 number인 경우 string은 불가
};

//+) 특정 속성을 고정하고 싶은 경우
interface Propss {
    name: string;
    [key: string]: string;
}

const pp: Propss = {
    name: "hello",
    a: "d",
    b: "e",
};

 

- key가 string인 경우, number가 key값이어도 가능 but, key가 number인 경우 string은 불가

 

 

2. `keyof` 연산자로 key들에 대한 type을 가져올 수 있다.

 

let keys: keyof Propss;
//결과 => let keys: string | number - key가 string인 경우 number 값도 가능하기 떄문

//+ 인덱스 타입이 아닌 인터페이스에 keyof 연산자 사용하면?
interface User {
    name: string;
    age: number;
    hello(msg: string): void;
}

let keyOfUser: keyof User;
// 결과 => let keyOfUser : "hello" | "name" | "age" 각 key를 union 타입으로 가져온다

'TypeScript' 카테고리의 다른 글

React + Typescript  (0) 2021.01.28
[TypeScript 강의노트] - generic  (0) 2021.01.21
[TypeScript 강의노트] - class  (0) 2021.01.21
[TypeScript 강의노트]  (0) 2021.01.21