티스토리 뷰

do/typescript

typescript 2

dooo.park 2019. 4. 10. 18:08

객체

중괄호{ }로 객체 타입(object type)을 선언한다.

const o: { a: string; b: number; } = { a: 'ab', b: 2};

콜론(:)의 우변에는 값 대신 해당 속성의 타입이 들어간다.
구분자로 콤마(,) 뿐만 아니라 세미콜론(;)을 사용할 수 있다.

 

선택 속성

속성명 뒤에 물음표(?)를 붙여 해당 속성이 존재하지 않을 수도 있음을 표현할 수 있다.

const o: { a: string; b?: number; } = { 
  a: 'ab' 
};

읽기 전용 속성

속성명 앞에 readonly 키워드를 붙여 해당 속성의 재할당을 막을 수 있다. 

const user: { 
  readonly a: string; 
  b: number; 
} = { a: 'ab', b: 2 };
user.name = 'cd'; // error TS2540: Cannot assign to 'a' because it is a constant 

type alias

이미 존재하는 타입에 다른 이름을 붙여 타입을 간단하게 쓸 수 있다.

alias를 쓴다고 해서 새로운 타입이 생성되는 것은 아니다.

type NewType = Type; // 타입 = 별칭(alias)

type a = string;
type b = number;
type c = a;
type d = d[];

type e = string;
function getUser(id: e) {
  /* 함수 본문 */
}
getUser(7); // error TS2345: Argument of type '7' is not assignable to parameter of type 'string'.

함수의 타입

함수의 타입을 결정하기 위해서는 두 가지가 필요하다.
① 매개변수(parameter)의 타입
② 반환값(return value)의 타입 (반환 타입)


매개변수의 경우, 변수의 타입을 표기할 때와 마찬가지로 매개변수 뒤에 콜론(:)을 붙이고 타입을 적는다. 

(param1: number)
반환 타입은 매개변수 목록을 닫는 괄호())와 함수 본문을 여는 여는 대괄호({) 사이에 콜론을 붙이고 표기한다. 

(function (): number { ... })

function sum(a: number, b: number): number {
  return (a + b);
}

함수가 아무런 값도 반환하지 않고 종료된다면 반환 타입으로 void를 사용한다.

function logGreetings(name: string): void {
  console.log(`Hello, ${name}!`);
}

void 반환 타입을 갖는 함수가 undefined나 null 이외의 값을 반환하면 타입 에러 발생

void가 아닌 반환 타입을 갖는 함수가 아무 값도 반환하지 않는 경우도 에러 발생

function notReallyVoid(): void {
  return 1;
}
// error TS2322: Type '1' is not assignable to type 'void'.

function actuallyVoid(): number { }
// error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value.

함수 값의 타입 표기

함수 타입의 값에 타입 표기를 붙이기 

(매개변수) => 반환 타입

매개변수가 없는 함수의 경우

() => 반환 타입

화살표 함수 문법 또한 비슷하게 정의 가능하다.

const yetAnotherSum: (a: number, b: number) => number = sum;
const onePlusOne: () => number = () => 2;
const arrowSum: (a: number, b: number) => number = (a, b) => (a + b);

타입 별칭도 사용 가능하다.

type SumFunction = (a: number, b: number) => number;
const definitelySum: SumFunction = (a, b) => (a + b);

매개변수 기본값

ES6와 마찬가지로, 타입스크립트에서도 기본 매개변수 문법을 사용할 수 있다. 

매개변수명: 타입 = 기본값
function greetings(name: string = 'stranger'): void {
  console.log(`Hello, ${name}`);
}
greetings('Heejong'); // Hello, Heejong!
greetings(); // Hello, stranger!

선택 매개변수

매개변수 뒤에 물음표(?)를 붙여 매개변수가 생략 될 수 있음을 명시할 수 있다.

 

optional?: number 로 선언된 선택 매개변수 optional를 함수 본문에서 number 타입 값으로 사용하려면 

해당 값이 undefined가 아닌지를 먼저 검사해야 한다.

function fetchVideo(url: string, subtitleLanguage?: string) {
  const option = { url };
  if (subtitleLanguage) {
    option.subtitleLanguage = true;
  }
  /* ... */
}
fetchVideo('https://example.com', 'ko'); // okay
fetchVideo('https://example.com'); // also okay

선택 매개변수 이후에 필수 매개변수를 두는 것은 허용되지 않는다.

필수 매개변수가 선택 매개변수 뒤에 있을 시, 인자가 어떤 매개변수의 값인지 구분할 수 없기 때문이다. 

function invalidFetchVideo(subtitleUrl?: string, url: string) {
  /* ... */
}
//error TS1016: A required parameter cannot follow an optional parameter.

두 함수를 아래와 같이 호출하는 경우

fetchVideo('https://example.com');
invalidFetchVideo('https://example.com');

첫 번째 호출의 경우 인자가 url 매개변수의 값이라는 것이 명백하다. 

한편 두 번째 호출에서는 'https://example.com' 이라는 값이 선택매개변수인 subtitleUrl의 값으로 쓰인건지, 

또는 url의 값으로 쓰인 건지 모호하다. 타입스크립트는 이런 식의 함수 정의를 만나면 오류를 발생시킨다.

 

함수 오버로딩

자바스크립트에서 한 함수가 여러 쌍의 매개변수-반환 타입을 갖는 경우가 매우 흔하다. 

이런 함수의 타입을 정의할 수 있게 타입스크립트는 함수 오버로딩(function overloading)을 지원한다.


타입스크립트 함수 오버로딩 특징
① 함수는 하나 이상의 타입 시그니처를 가질 수 있다.
② 함수는 단 하나의 구현을 가질 수 있다.


오버로딩을 통해서 여러 형태의 함수 타입을 정의할 수 있지만 실제 구현은 한 번만 가능하므로 

여러 경우에 대한 분기는 함수 본문 내에서 이루어져야 한다.

function doubleString(str: string): string {
    return `${str}${str}`;
}
function doubleNumber(num: number): number {
    return (num * 2);
}
function doubleBooleanArray(arr: boolean[]): boolean[] {
    return arr.concat(arr);
}

이 함수들은 각각 문자열, 숫자, 그리고 불리언의 배열을 받아 두 배로 만드는 함수다. 

이 때, ‘두 배’가 의미하는 건 타입에 따라 다르고, 세 함수는 인풋 타입에 따라 다른 타입의 값을 반환한다. 

 

이 세 함수를 함수 오버로딩을 사용해서 하나의 double 이라는 함수로 합쳐보자.

먼저 각 경우의 타입 시그니쳐를 정의한다. 타입 시그니쳐는 함수 정의와 동일하되, 본문이 생략된 형태다.

function double(str: string): string;
function double(num: number): number;
function double(arr: boolean[]): boolean[];

그 후에 함수의 본문을 구현한다.

function double(arg) {
    if (typeof arg === 'string') {
        return `${arg}${arg}`;
    } else if (typeof arg === 'number') {
        return arg * 2;
    } else if (Array.isArray(arg)) {
        return arg.concat(arg);
    }
}

이렇게 오버로딩을 통해 정의된 double 함수는 호출하는 인자의 타입에 따라 반환 타입이 달라진다.

const num = double(3); // number
const str = double('ab'); // string
const arr = double([true, false]); // boolean[]

This 타입

자바스크립트 함수 내부에서의 this 값은 함수가 정의되는 시점이 아닌 실행되는 시점에 결정된다.

이런 특성은 함수 내부에서 this 의 타입을 추론하는 일을 매우 어렵게 만든다. 

 

타입스크립트는 함수 내에서의 this 타입을 명시할 수 있는 수단을 제공한다.
함수의 this 타입을 명시하기 위해 함수의 타입 시그니쳐에서 매개변수 가장 앞에 this를 추가한다. 

이 때 this 타입은 타입 시스템을 위해서만 존재하는 가짜 타입이다. 

this 매개변수를 추가 해도 함수가 받는 인자 수와 같은 실제 동작은 변하지 않는다.

interface HTMLElement {
  tagName: string;
  /* ... */
}
interface Handler {
  (this: HTMLElement, event: Event, callback: () => void): void;
}
let cb: any;
// 실제 함수 매개변수에는 this가 나타나지 않음
const onClick: Handler = function(event, cb) {
  // this는 HTMLElement 타입
  console.log(this.tagName);
  cb();
}

this의 타입을 void로 명시하면 함수 내부에서 this에 접근하는 것을 막을 수 있다.

interface NoThis {
  (this: void): void;
}
const noThis: NoThis = function() {
  console.log(this.a); // Property 'a' does not exist on type 'void'.
}

 


참고사이트

https://ahnheejong.gitbook.io/ts-for-jsdev

 

 

'do > typescript' 카테고리의 다른 글

typescript 5  (0) 2019.04.16
typescript 4  (0) 2019.04.14
typescript 3  (0) 2019.04.12
typescript 1  (0) 2019.04.09
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함