TypeScript 기초문법에 관하여

🪐 C:on·2021년 12월 23일
0

타입스크립트

목록 보기
1/3


🔎 기본타입

  • boolean
  • number
  • string
  • 배열
    • 숫자를 가지는 배열의 타입 예
    • nubmer[]
    • Array
  • 튜플
    • 요소의 타입과 개수가 고정된 배열을 표현
    • 예 : [string, nubmer]
  • any
    • 타입검사를 하지 않고 컴파일 시간에 통과하도록 할 때 사용
  • void
    • 함수에서 반환값이 없을 때 사용
  • object
    • 원시타입(number, string, boolean 등)이 아닌 타입을 나타낸다.



🔎 인터페이스

선택적 프로퍼티

인터페이스의 모든 프로퍼티가 필요하지 않을 수 있다.

선택적 프로퍼티를 가지는 인터페이스는 프로퍼티 이름 끝에 ?를 붙여 표시한다.

interface SquareConfig {
    color?: string;
    width?: number;
}

읽기전용 프로퍼티

프로퍼티 중 어떤것은 객체가 생성될 때만 수정가능해야할 수 있다.

프로퍼티 이름 앞에 readonly를 넣어서 읽기 전용으로 지정할 수 있다.

interface Point {
    readonly x: number;
    readonly y: number;
}

초과 프로퍼티

interface SquareConfig {
    color?: string;
    width?: number;
}

//createSquare라는 함수가 SquareConfig 타입 객체를 인자로 받는 다고 가정할 때

let mySquare = createSquare({ colour: "red", width: 100 });

타입스크립트에서 객체리터럴은 다른 변수에 할당할 때나 인수로 전달할 때, 초과 프로퍼티 검사를 받는다.
이 검사에서 만약 객체리터럴이 위 예제처럼 대상 타입이 가지고 있지 않은 프로퍼티를 가지고 있으면 에러가 발생한다.

초과 프로터피 검사를 피하는 방법은 세가지이다.

  • 타입단언
    • let mySquare = createSquare({ width: 100, opacity: 0.5 } as SquareConfig);
  • 문자열 인덱스 서명
    • 추가 프로퍼티가 있음을 확신할 때
    • 대상 타입의 프로퍼티에 [propName: string]: any;를 추가한다.
  • 객체를 다른 변수에 할당하기
    let squareOptions = { colour: "red", width: 100 };
     let mySquare = createSquare(squareOptions);
    • 객체 리터럴만 초과프로퍼티검사를 받기 때문에 변수를 전달하면 검사를 피할 수 있다.

클래스 타입

클래스가 충족시켜야 하는 규약을 인터페이스로 정의할 수 있다.

클래스는 static타입과 instance타입을 가진다. 규약에 의한 검사는 인스턴스만 이루어지며 스태틱은 검사에 포함되지 않는다. 생성자가 검사에 포함되지 않는 이유가 생성자 역시 스태틱이기 때문이다.


인터페이스 확장

extends를 사용해서 인터페이스의 재사용이 가능하다.

인터페이스를 재사용성이 높은 컴포넌트로 쪼갤 때, 유연함을 제공해준다.

interface Square extends Shape, PenStroke {
    sideLength: number;
}

이렇게 하나의 인터페이스는 여러개의 인터페이스를 확장할 수도 있다.


클래스를 확장한 인터페이스

인터페이스가 클래스를 확장하면 클래스의 멤버는 상속받지만 구현은 상속받지 않는다.

말이 어려우니 예제로 보는것이 이해에 더 도움이 된다.

class Control {
    private state: any;
}

interface SelectableControl extends Control {
    select(): void;
}

// Error: Property 'state' is missing in type 'Image'.
class Image implements SelectableControl {
    private state: any;
    select() { }
}

인터페이스는 클래스를 상속했다.
클래스의 멤버를 구현하기 위해서는 그 클래스나 하위클래스로만 구현이 가능하다.

ImageControl의 하위클래스가 아니므로 state를 구현할 수 없는 것이다.




🔎 함수

매개변수

선택적 매개변수를 원한다면 매개변수 이름 끝에 ? 를 붙임으로써 해결할 수 있다.

function buildName(firstName: string, lastName?: string) {
    if (lastName)
        return firstName + " " + lastName;
    else
        return firstName;
}

매개변수 초기화

메개변수에 = 값 을 통해서 전달되지 않은 인수의 기본값을 지정해 줄 수 있다.

보통은 이러한 매개변수는 순서상 뒤쪽에 위치하는 데 만약 앞쪽에 위치하고 있을 경우에는 함수 사용시 인자를 어떻게 전달할 수 있을 까

function buildName(firstName = "Will", lastName: string) {
    return firstName + " " + lastName;
}

let result4 = buildName(undefined, "Adams");     // 성공, "Will Adams" 반환

이렇게 사용자가 명시적으로 undefined 를 전달해 줌으로써 초기화 매개변수를 볼 수 있다.


나머지 매개변수

언젠가는 다수의 매개변수를 그룹지어 작업하기를 원하거나, 함수가 최종적으로 얼마나 많은 매개변수를 취할 지 모를 수 있다.

function buildName(firstName: string, ...restOfName: string[]) {
    return firstName + " " + restOfName.join(" ");
}


let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");

...을 통한 나머지매개변수를 이용하면 선택적 매개변수의 수를 무한으로 취급한다.




🔎 this

this는 함수가 호출될 때 정해지는 변수이다.


this와 화살표 함수

let deck = {
    suits: ["hearts", "spades", "clubs", "diamonds"],
    cards: Array(52),
    createCardPicker: function() {
        return function() {
            let pickedCard = Math.floor(Math.random() * 52);
            let pickedSuit = Math.floor(pickedCard / 13);

            return {suit: this.suits[pickedSuit], card: pickedCard % 13};
        }
    }
}

let cardPicker = deck.createCardPicker();
let pickedCard = cardPicker();

cardPicker에 의한 return문의 thisdeck이 아닌 undefined가 된다.
왜냐하면 함수 자체적인 호출이므로 발생된 객체가 없기 때문이다.


이 문제를 해결하기 위해서 화살표함수를 사용하여 알맞은 바인딩을 해줄 수 있다.

let deck = {
    suits: ["hearts", "spades", "clubs", "diamonds"],
    cards: Array(52),
    createCardPicker: function() {
        return () => {
            let pickedCard = Math.floor(Math.random() * 52);
            let pickedSuit = Math.floor(pickedCard / 13);

            return {suit: this.suits[pickedSuit], card: pickedCard % 13};
        }
    }
}

화살표함수는 함수가 호출된 곳이 아닌 함수가 생성된 쪽의 this를 캡쳐한다.


this의 any 타입 해결하기

위 예제의 this.suits[pickedSuit]의 타입은 any가 되어 경고가 표시될 수 있다.

가짜 this를 만들어서 매개변수에 전달하여 이 문제를 해결할 수 있다.

interface Card {
    suit: string;
    card: number;
}
interface Deck {
    suits: string[];
    cards: number[];
    createCardPicker(this: Deck): () => Card;
}
let deck: Deck = {
    suits: ["hearts", "spades", "clubs", "diamonds"],
    cards: Array(52),
    createCardPicker: function(this: Deck) {
        return () => {
            let pickedCard = Math.floor(Math.random() * 52);
            let pickedSuit = Math.floor(pickedCard / 13);

            return {suit: this.suits[pickedSuit], card: pickedCard % 13};
        }
    }
}

타입스크립트에게 createCardPickerDeck 객체에서 호출된다는 것을 알려주면, thisDeck타입이 되며 any타입에 의한 오류는 발생하지 않게된다.


0개의 댓글