타입스크립트 교과서 2.9~2.11정리

이수빈·2023년 9월 13일
1

Typescript

목록 보기
2/17
post-thumbnail

인터페이스

  • type선언과 마찬가지로 대문자로 선언하는게 관습

인덱스 시그니처(Index Signature)

  • 인터페이스에서 프로퍼티에 어떤 key 값이 오는지 특정 할 수 없을때

  • 객체에서 key 값을 동적으로 받을때 사용함(프로퍼티 name을 모를때)


interface Arr{
    length : number;
    [key : number] : string;
} // length 라는 속성을 제외한 속성키는 모두 number임, 속성키에 해당하는 value는 string이여야함.

const arr:Arr = ['3', '5', '7'];

인터페이스 선언병합

  • 같은 이름으로 여러 인터페이스 선언가능함 그럼 모든 인터페이스가 하나로 합쳐지는 것

  • 따로 병합을 안해줘도 됨 => 다른 사람이 수정해도되는 객체타입을 인터페이스로 선언하면 다른 개발자는 동일한 이름의 인터페이스를 만들어서 수정가능

  • 속성 이름이 겹치는데 타입이 다를 경우 에러발생

namespace

  • 인터페이스 선언병합의 단점을 해결함 ( 의도치 않게 합쳐지는 것을 방지함)

  • 네임스페이스 내부타입을 사용하려면 export해야함

namespace Example{
    export interface Inner{
        test : string;
    }
}

const ex1:Example.Inner ={
    test: "hiello",
}
  • 네임스페이스 자체도 중첩가능 이 경우 내부 namespace export 필요함.

namespace Outer{
    export namespace Example{
    export interface Inner{
        test : string;
    }
   }
}


const ex1:Outer.Example.Inner ={
    test: "hiello",
}
  • 네임스페이스 자체를 JS값처럼 사용 할 수 있음

  • 네임스페이스도 이름이 겹치는 경우 병합됨 => 이를 방지하기 위해 묘듈이 존재함.

객체의 속성, 메서드 적용 특징

  • optional(있어도, 없어도 무관) , readonly(선언되면 변경불가능) 존재
interface Example{
    hello: string;
    world?: number; //number|undefined type
    readonly wow : boolean;
    readonly multiple? : symbol;
}

const example:Example = {
    hello: 'hi',
    wow : false,
}

example.no; // error 없음
example.wow = true; // error 변경불가능
  • 객체리터럴을 대입했냐 vs 변수를 대입했냐의 여부에 따라 type 검사방식이 달라짐

  • 객체리터럴을 interface 타입으로 선언하면 형태가 똑같아야함, 변수를 인터페이스로 선언하고 대입하면 optional이 됨.


{
    interface Example{
        hello:string;
    }

    const example:Example = {
        hello:'hi',
        why : '나만에러야',
    } // 이건 에러

    const obj = {
        hello:'hi',
        why : "나는에러아냐",
    }

    const example2 :Example = obj; //에러아님
}
  • 함수에서도 동일함.

  • 객체 리터럴을 대입하면 => 잉여속성 검사가 실행됨(타입선언에서 선언하지 않은 속성을 사용할 때 에러를 표시함)

  • 변수를 대입할 때 => 객체 간 대입 가능성을 비교함.

{
    interface Money{
        amount : number;
        unit : string;
    }

    const money = {amount : 1000, unit:"won", error:"에러아님"}

    function addMoney(money1:Money, money2:Money):Money{
        return {
            amount : money1.amount+money2.amount,
            unit : 'won'
        }
    }

    addMoney(money, {amount:3000, unit: "money", error :"에러"}) //error
}

인덱스 접근 타입

  • 타입추출 => 객체의 속성에 접근해서 type 연동가능

  • Animal의 속성 type만 변경하면 나머지코드는 신경쓰지 않아도 됨.

{
    type Animal = {
        name: string;
    }

    type N1 = Animal['name'];
    type N2 = Animal["name"];
    type N3 = Animal.name; // error
}
  • 객체 keyof 연산자 : keyof 연산자를 object에 사용하면 object가 가지고 있는 모든 key값을 union type으로 합쳐서 내보내 준다.

  • key의 type을 얻으면 value의 type도 얻을 수 있다.

  • 배열에 keyof 적용하면 => number | 배열속성이름유니언 | 배열인덱스 문자열유니언

{
    const obj = {
        hello :"world",
        name : "zero",
        age : 28,
    }

    type Keys = keyof typeof obj; // "hello"|"name"|"age"
    type Values = typeof obj[Keys]; // value type 뽑기
  
    type Keys1 = keyof any;
    type ArrayKeys = keyof [1,2,3];
    let a :ArrayKeys = "lastIndexOf";
    a = "length";
    a = "2";
    a = "3"; // 안됨 
    a = 3
}
  • 객체에서 key로 type추출하기 & 메서드 선언방식
{
     const obj = {
        hello :"world",
        name : "zero",
        age : 28,
    }

    type Values = typeof obj["hello" | "name"];

    interface Example{
        a() :void;
        b: () => void;
        c:{
            ():void;
        }
    } 

}

매핑된 객체타입

  • 인덱스 시그니처에서 사용 할 수 있는 타입은 string, number, symbol, 템플릿리터럴, 유니언뿐임(결국 인덱스 시그너처를 사용하는 이유 => key를 특정 할 수 없는 경우임)

  • 여기서 리터럴타입과 템플릿리터럴 타입은 다름

   type word = "hi";
    type word2 = `hi ${word}`
  • 매핑된 객체타입이란? 기존의 다른 타입으로 부터 새로운 객체 속성을 만들어내는 타입

  • 매핑된 타입은 key의 조합을 사용해 키를 통해 탕입을 반복적으로 생성하는 제너릭 타입임.

  • in 연산자 사용함 => in연산자 오른쪽에는 유니언타입이 와야함. (속성이 하나하나 평가되어 type으로 변환됨)

  • 기존 객체타입을 복사할때 많이 사용함.


{
    type HelloAndHi = {
        [key : "hello"| "hi"] : string;
    }

    type HelloAndHi2 = {
        [key  in "hello"| "hi"] : string;
    }
    
     interface Original{
        name : string;
        age : number;
        married : boolean;
    }

    type Copy =  {
        [key in keyof Original] : Original[key];
    }
  
   type Tuple = [1,2,3];
    type CopyTuple = {
        [key in keyof Tuple] : Tuple[key];
    } 
  // Tuple 객체의 전체 type 복사함.

    type CopyTuple2 = Tuple // 이건 [1,2,3] tuple타입으로

}
  • 기존의 객체 type을 복사할때, 수식어를 추가하거나 제거가능함. as 키워드를 통해 속성이름또한 변경가능

  • (-)의 의미는 속성을 제거함.

{
    interface Original{
        name : string;
        age : number;
        married : boolean;
    }
     type Copy =  {
        -readonly [key in keyof Original]? : Original[key];
    } 
}

타입을 집합으로

  • 유니온 => 합집합, intersection => 교집합

  • 전체집합은 unknown, 공집합은 never 개념, 항상 좁은타입에서 넓은타입으로 대입해야함. (좁은타입은 넓은타입에 대입가능)

profile
응애 나 애기 개발자

0개의 댓글