타입스크립트 정리

Plato·2022년 7월 15일
0

타입스크립트로 계산기를 만들어보며, 배웠던 점을 정리하고자 한다.

type assertion

타입스크립트는, 타입을 추론한다. 이때, 우리가 타입을 더 잘 알고 있다고 판단이 들면, type assertion을 통해, 이를 알릴 수 있다. 타입을 표명하면, 타입스크립트가 추론한 타입이 아닌, 사용자가 표명한 타입을 받아들인다. 이때 실제로 해당 타입이 아니더라도, 타입스크립트가 받아들이기 때문에, 아주 안전한 방법은 아니다.
사용법: value as type

예시
const $result = document.querySelector("#result") // 타입스크립트는, querySelector('#result')가 반환하는 값의 타입이 'Element'라 판단한다.
const $result = document.querySelector('#result') as HTMLElement; // querySelector('#result')가 반환하는 값의 타입은 HTMLElement임을 표명할 수 있다.

index signature

객체 타입을 생성할 때, 타입의 프로퍼티들을 미리 다 알 수 없지만, 프로퍼티들이 어떤 형태를 가져야 하는지는 알 수도 있다. 이때, index signature를 사용하여, 형태를 알릴 수 있다. index signature 파라미터의 타입은 string, number, symbol 혹은 template literal일 수 있다.
사용법: [signature_parameter: type]: type

예시
type Person = {
    [index: string]: string;// Person타입 객체 프로퍼티의 key가 string이라면, value도 string이어야만 한다.
    name: string;
    sex: string;
    height: number; // key가 string일 때, string이 아닌 값을 가질 수 없다.
    3: number; // 여기서 3은 숫자가 아니라 string이다. 그래서 value도 string이어야 한다.
}

유의할 점은, 시그니처 파라미터의 타입을 string으로 하면, 위의 예시에서와 같이 key의 타입이 number일 때도 적용되지만, 역방향은 적용되지 않는다. 즉 시그니처 파라미터의 타입을 number로 하면, key의 타입이 string일 때 적용되지 않는다.

type Person = {
    [key: number]: number;
    name: string;
    sex: string;
}

let myPerson: Person = {
    name: 'Ben', // 파라미터의 타입이 number이기 때문에, key가 string일 때 value가 number가 아니여도 된다.
    sex: 'Male',
    3: 'foo', // 에러가 발생한다.
}

유니온과 함께 사용할 수 있다.

예시
type Person = {
    [index: string]: string | number;// Person타입의 객체의 프로퍼티는, key가 string일 때, value는 string혹은 number이어야 한다.
    name: string;
    sex: string;
	height: number; // 에러가 발생하지 않는다.
}

또한 readonly와 함께 사용할 수 있다.

예시
type Person = {
    readonly [index: string]: string | number
    name: string;
    sex: string;
}

let myPerson: Person = {
    name: "Ben",
    sex: "Male",
    height: "unknown",
}

myPerson.name = 'Jenny'; // 에러가 발생하지 않는다.
myPerson.sex = "Female"; // 에러가 발생하지 않는다.
myPerson.height = 'tall' // 에러가 발생한다. readonly가 적용된 것. name과 sex는 타입 별칭 생성 시에 포함돼있어서, readonly가 적용되지 않는 것.

keyof

keyof 연산자는, 객체 타입을 받고, 키의 문자열 혹은 숫자 리터럴 유니온을 생성한다.
사용법: keyof 객체_타입

예시
type Person = {name:string; sex: string}
type foo = keyof Person; // 이는 type foo = 'name' | 'sex' 와 동일하다.

mapped types

많은 경우, DRY한 코드를 위해, 다른 타입을 확장하여 사용하고 싶을 수 있다. mapped types는 이때 유용하다. 문법은, index signature의 문법과 매우 유사하다.
사용법: [key in 유니온_타입]: type

예시
type Operator = '+' | '-' | '/' | '*';

type Operations = {
    [key in Operator]: Function;
}

let myOperations: Operations = {
    '+': 34, // 에러. 함수가 할당돼야 함.
    '-' : 24, // 에러
    '/' : 10, // 에러
    '*' : 55, // 에러
}

위에서 설명한 keyof와 같이 사용할 수 있다.

예시
let Operator = {
    '+': 0,
    '-': 1,
    '/': 2,
    '*': 3,
    }

type Operations = {
    [key in keyof typeof Operator]: Function;
}

let myOperations: Operations = {
    '+': ()=>{console.log('lol')},
    '-': ()=>{console.log('lol')},
    '/': ()=>{console.log('lol')},
    '*': ()=>{console.log('lol')},
}

0개의 댓글