TypeScript Study day-1 _ basic type

hwibaski·2021년 12월 15일
0

TypeScript & JavaScript

목록 보기
10/15

드림코딩엘리님의 TypeScript 강의를 토대로 정리했습니다.

1. Basic

1-1. number

const num: number = 1;

1-2. string

const str: string = 'hello';

1-3. boolean

const bool: boolean = false;

1-4. undefined

  • 아래와 같은 undefined 타입 지정은 모순적이다.
  • name이라는 변수에 데이터를 넣으려고 선언을 했는데. undefined 라는 것이 의미적으로 앞뒤가 맞지 않는다.
  • undefined 로 선언된 변수에는 undefined 외에는 지정이 불가하다.
let name: undefined; // 💩 not good -> useless
name = 'Hwibaski' // error

타입이 string일 수도 있고, undefined일 수도 있다면 union type을 사용하자.

let age: number | undefined;
age = undefined;
age = 1;

// find  함수는 number를 리턴할 수도 있고, undefined를 리턴할 수도 있다.
const find = function (): number | undefined {
  return 1 || undefined;
};

1-5. null

  • nullundefined 와 비슷한 맥락으로 값이 없다는 것이지만 명시적으로(의도적으로) 값이 없음을 나타낸다.
let person: null; // 💩 not good -> useless
let person2: string | null;
person = null;
person2 = 'hello';

1-6. unknown

  • 어떠한 타입인지 알 수 없음을 의미 → 그러므로, 어떤 타입이든 지정이 된다.
let notSure: unknown = 0;
notSure = 'he';
notSure = true;

1-7. any

  • 어떠한 타입이든 사용이 가능 → 그러므로, 아무 타입이든 지정이 된다.
let anything: any = <0;
anything = 'hello';
anything = 1;

unknownany 는 사실상 typescript를 사용하는 의미를 퇴색시킨다. 정말 필요한 곳 외에는 사용을 지양하자.

1-8. void

  • 함수의 리턴 타입을 정의하는 데 주로 사용
// void : 아무것도 리턴하지 않는다, 다만 리턴문은 한다.
function print(): void {
  console.log('hello');
  return;
}

// return 문이 없지만 내부적으로 return undefined가 생략되어 있으므로
// 아무것도 void 타입이다.
function print(): void {
  console.log('hello');
  // return undefined -> return문이 없을 시,
  // JavaScript 내부적으로 return undefined를 한다.
}
  • 변수에서의 void
  • 변수에서 void 타입을 지정하면 undefined 만 할당이 가능하기 때문에, 활용성이 떨어진다.
let useless: void = undefined; // 💩
let useless = '123' // error

1-9. never

  • void 타입은 아무것도 리턴을 하지 않을 때 사용을 했다.
  • never 타입은 return 자체를 하지 않을 때 사용을 한다.
  • 주로 throw new Error() 와 같은 에러 핸들링에 사용된다.
// never : return 자체를 하지 않는다.
function throwError(message: string): never {
  // message => server (log) 
	
  // 1 : error 핸들링의 경우
  throw new Error(message);
  // 2 : 무한 루프 역시 아무것도 리턴하지 않으므로 never 타입이다.
  while (true) {
    // ...
  }
}

// 이런 식으로 사용하는 경우는 없다.
let neverEnding: never; // 💩

1-10. object

  • 원시타입을 제외한 모든 object 타입을 지정할 수 있다.
  • 함수의 매개변수로 object 타입을 지정할 경우, 너무 광범위한 값들이 올 수 있기 때문에 썩 좋은 타입은 아니다.
let obj: object; // 💩
obj = [1, 2, 3]
obj = { test: 'test'}
function acceptSomeObject(obj: object) {} // 
// 💩 -> 어떠한 객체(배열)이든 받아들을 수 있다. 너무 광범위 하다...
acceptSomeObject({ name: 'hwimin' });
acceptSomeObject({ animal: 'dog' });

2. Type in Function

2-1. 일반적인 사용 방법

// JavaScript
function jsAdd(num1, num2) {
  return num1 + num2;
}

// TypeScript
function add(num1: number, num2: number): number {
  return num1 + num2;
} 

2-2. promise 를 리턴할 경우

// JavaScript
function jsFetchNum(id) {
  // code..
  // code..
  return new Promise((resolve, reject) => {
    resolve(100);
  });
}

// TypeScript
// string인 id를 받아서 Promise를 return 하는데,
// resolve 시 값이 number이다.
function fetchNum(id: string): Promise<number> {
  // code ...
  return new Promise((resolve, reject) => {
    resolve(100);
  });
}

2-3. optional parameter

  • 함수의 매개변수에서 특정 매개변수가 없는 경우가 없는 경우가 있을 수 있다.
  • 그럴 때는 optional parameter를 사용한다.
  • 아래의 코드에서 lastName 매개변수는 string 일 수도 있고, undefined일 수도 있다.

parameter?: type

function printName(firstName: string, lastName?: string) {
  console.log(firstName);
  console.log(lastName);
}
printName('Steve', 'Jobs'); // 'Steve', 'Jobs'
printName('Hwimin');        // 'Hwimin', undefined
printName('Anna', undefined); // 'Anna', undefined
printName('Anna', 123) // error

2-3-1. union type으로 해결할 수 있는거 아니야?

  • 똑같은 코드를 가지고 lastName 매개변수만 union type으로 지정해보자
  • 컴파일 에러가 난다. → optional parameter 대신 union 타입을 사용 시, 무조건 특정한 값이 있어야 한다.
  • 없는 값을 undefined 로 명시해줘야하므로, 유연하지 못하고 불필요한 코드도 생성된다.
function printName(firstName: string, lastName: string | undefined) {
  console.log(firstName);
  console.log(lastName);
}
printName('Steve', 'Jobs'); // 'Steve', 'Jobs'
printName('Hwimin');        // error -> why? union type으로 지정 시 무조건 값이 있어야한다. 
printName('Hwimin', undefined); // 'Hwimin', undefined
printName('Anna', undefined); // 'Anna', undefined
printName('Anna', 123) // error

2-4. default parameter

  • JS에서도 default parameter 를 사용할 수 있다.
  • TS 에서도 default parameter를 사용할 수 있다.
function printMessage(message: string = 'default message') {
  console.log(message);
}

// 아무 인수도 넣지 않았지만, 'default message'가 출력된다.
printMessage(); // 'default message'

2-5. rest parameter

  • rest parameter는 JS에서 기본적으로 사용가능하다.
  • ...parameter 의 형태로 매개변수를 지정하고, 인수로 여러 개의 값들을 입력할 시 parameter에 인수의 값들이 배열로 저장된다.
const add = function(...numbers) {
  console.log(numbers);
}
add(2, 3) // [2, 3]
add(5, 3, 7, 2) // [5, 3, 7, 2]
add(8, 2, 5, 3, 2, 1, 4) // [8, 2, 5, 3, 2, 1, 4]
  • typescript에서는 ...parameter의 타입을 지정해 줄 수 있다. 즉, 매개변수로 들어올 배열들의 각 요소의 타입을 지정할 수 있다.
// JavaScript
function addNumbers(...numbers) {
  return numbers.reduce((a, b) => a + b);
}

// TypeScript
function addNumbers(...numbers: number[]): number {
  return numbers.reduce((a, b) => a + b);
}
console.log(addNumbers(1, 2));             // 3
console.log(addNumbers(1, 2, 3, 4));       // 10
console.log(addNumbers(1, 2, 3, 4, 5, 0)); // 15
console.log(addNumbers(1, '1'));           // compile error

2-5-1. JavaScript 라면 어땠을까?

  • 아래의 함수는 매개변수로 받는 모든 값들을 더한 값을 리턴하는 것이 목표이다.
  • addNumbers 의 인수에 문자열을 넣어보자.
  • 개발자의 의도와 전혀 다른 방향으로 실행되어버린다.
// JavaScript
function addNumbers(...numbers) {
  return numbers.reduce((a, b) => a + b);
}

console.log(addNumbers(1, '1')) // '11' -> 끔찍하다.

3. Type with Array

3-1. Array의 타입을 지정하는 방법

const alphabet: string[] = ['a', 'b'];
const alphabet: Array<string> = ['a', 'b'];

3-2. 두 방법의 차이점은?

  • readonly 의 사용가능 여부가 다르다.
    • 1번 방법의 경우 readonly 사용가능
    • 2번 방법은 경우 readonly 사용불가
    • 21.01.12 수정 두 문법 모두 사용 가능함
 ** readonly를 구현하는 방법 ** 

const alphabet1: readonly string[] = []
const alphabet2: ReadonlyArray<string> =[]
const alphabet3: Readonly<string[]> = []
  • readonly 란?
// readonly를 추가할 경우 매개변수 alphabet의 값을 읽을 수만 있다.
// alphabet의 값을 수정할 수 없다.
// alphabet.push() 같은 메서드를 pirntArray 함수 내부에서
// 사용할 수가 없다는 뜻이다.
function printArray(alphabet: readonly string[]) {}

💡readonly 가 굉장히 많이 쓰이기 때문에 1번 방법을 사용하자! -> 취향껏 사용하자

3-3. Tuple

  • Tuple 이란?
  • 배열과 유사하지만 서로 다른 타입의 데이터를 담을 수 있는 타입이다.
let student: [string, number];
student = ['name', 123];
student[0]; // name
student[1]; // 123

tuple 의 사용은 권장되지 않는다. -> 드림코딩 엘리님의 의견

  • 인덱스에 따라 값을 찾는다. 이는 어떤 값이 있는지 파악하기가 어렵다.
  • 게다가 각 요소의 타입도 통일되어 있지 않다.
  • tuple을 사용할만한 곳에는 interface, type alias, class로 대체해서 사용한다.
  • array 구조분해로 가독성을 높힐 수는 있지만, 굳이? React Hook, useState()가 tuple의 좋은 사용 예
  • 동적으로 관리해야하는 것이 있는데 interface, type alias, class로 관리하기 어렵다면 tuple 을 사용한다.

reference

https://academy.dream-coding.com/courses/typescript
https://yamoo9.gitbook.io/typescript/
도서 타입스크립트 프로그래밍

0개의 댓글