스파르타코딩클럽 내일배움캠프 TIL58

한재창·2023년 1월 18일
0

TypeScript

Enum Type

  • 숫자형 이넘
enum Direction {
  Up,
  Down,
  Left,
  Right,
}

const up: Direction = Direction.Up;
// Direction = Direction.UP | Direction.Down | Direction.Left | Direction.Right
const leftOrRight: Direction.Left | Direction.Right = Direction.Left;
  • 문자형 이넘
enum Direction {
    Up = "UP",
    Down = "DOWN",
    Left = "LEFT",
    Right = "RIGHT",
}
  • 복합 이넘
enum BooleanLikeHeterogeneousEnum {
    No = 0,
    Yes = "YES",
}
// 권고하지 않음

유니온 Type

  • 유니온(Union) 타입 : (A || B)
    • 자바스크립트의 OR 연산자 || 와 같은 의미
    • | 연산자를 이용하여 타입을 여러 개 연결하는 방식
const printOut = (input: string | number) => {
	console.log(input);
}

printOut('문자열');
printOut(20);
printOut(true); // Error
  • 유니온 타입의 장점
function getAge(age: any) {
  age.toFixed(); // Error
  return age;
}

getAge('20');
getAge(20);
function getAge(age: number | string) {
  if (typeof age === 'number') {
    age.toFixed();
    return age;
  }
  if (typeof age === 'string') {
    return age;
  }
}

getAge('20');
getAge(20);
function padLeft(value: string, padding: any) {
  if (typeof padding === 'number') {
    return Array(padding + 1).join(' ') + value;
  }
  if (typeof padding === 'string') {
    return padding + value;
  }
  throw new Error(`Expected string or number, got '${padding}'.`);
}

console.log(padLeft('Hello world', 4)); // "    Hello world"
console.log(padLeft('Hello world', '!!!')); // "!!!Hello world"
console.log(padLeft('Hello world', true)); // Error

Type Alias (사용자 정의 타입)

const hero1: { name: string; power: number; height: number } = {
  name: '슈퍼맨',
  power: 1000,
  height: 190,
};

const printHero = (hero: { name: string; power: number; height: number }) => {
  console.log(hero.name, hero.power);
};

console.log(printHero(hero1));
  • 매번 타입을 새로 작성하는 건 번거롭고 재사용이 불가능하다.
    • type 키워드 사용하기
// type.ts

type Hero = {
	name: string;
	power: number;
	height: number;
};
import type { Hero } from './type';

const hero1: Hero = {
  name: '슈퍼맨',
  power: 1000,
  height: 190,
};

const printHero = (hero: Hero) => {
  console.log(hero.name, hero.power);
};

console.log(printHero(hero1));
type Direction = 'UP' | 'DOWN' | 'LEFT' | 'RIGHT';

const printDirection = (direction: Direction) => {
  console.log(direction);
};

printDirection('UP');
printDirection('UP!');

interface

  • 기본 정의
interface Person {
  name: string;
  age: number;
}

const person1: Person = { name: 'js', age: 20 };
const person2: Person = { name: 'ljs', age: 'twenty' }; // Error
  • 선택 속성
interface Person {
  name: string;
  age?: number;
}

const person1: Person = { name: 'js' };
  • Read only 속성
interface Person {
  readonly name: string;
  age?: number;
}

const person1: Person = { name: 'js' };
person1.name = 'ljs'; // Error

let readOnlyArr: ReadonlyArray<number> = [1,2,3];
readOnlyArr.splice(0,1); // error
readOnlyArr.push(4); // error
readOnlyArr[0] = 100; // error
  • index type
interface Person {
  readonly name: string;
  [key: string]: string | number;
}

const p1: Person = { name: 'js', birthday: '비밀', age: 20 };
  • 함수 타입
interface Print {
  (name: string, age: number): string;
}
// type Print = (name: string, age: number) => string;

const getNameAndAge: Print = function (name, age) {
  return `name: ${name}, age: ${age}`;
};
  • 인터페이스 확장
interface Person {
  name: string;
  age: number;
}

interface Korean extends Person {
  birth: 'KOR';
}

interface Korean {
  name: string;
  age: number;
  birth: 'KOR';
}

interface Developer {
  job: 'developer';
}

interface KorAndDev extends Korean, Developer {}

interface KorAndDev {
  name: string;
  age: number;
  birth: 'KOR';
  job: 'developer';
}
  • intersection Type: 여러 타입을 모두 만족하는 하나의 타입
interface Person {
  name: string;
  age: number;
}

interface Developer {
	name: string;
  skill: string;
}

type DevJob = Person & Developer;

const nbcPerson: DevJob = {
  name: 'a',
  age: 20,
  skill: 'ts',
};

  • type vs interface
    • 타입 별칭과 인터페이스의 가장 큰 차이점은 타입의 확장 가능 / 불가능 여부이다.
    • 인터페이스는 확장이 가능한데 반해 타입 별칭은 확장이 불가능하다.
    • 따라서, 가능한한 type 보다는 interface로 선언해서 사용하는 것을 추천합니다.

제네릭

  • 제네릭이란 타입을 마치 함수의 파라미터처럼 사용하는 것
function getText(text: any): any {
  return text;
}

getText('hi'); // 'hi'
getText(10); // 10
getText(true); // true
function getText<T>(text: T): T {
  return text;
}

getText<string>('hi');
getText<number>(10);
getText<boolean>(true);
  • 추가 예시
// 제네릭 X

function getItemArray(arr: any[], index: number): any {
  return arr[index];
}

function pushItemArray(arr: any[], item: any): void {
  arr.push(item);
}

const techStack = ['js', 'react'];
const nums = [1, 2, 3, 4];

getItemArray(techStack, 0); // 'js'
pushItemArray(techStack, 'ts'); // ['js', 'react', 'ts']

getItemArray(nums, 0); // 1
pushItemArray(nums, 5); // [1, 2, 3, 4, 5];
// 제네릭

function getItemArray<T>(arr: T[], index: number): T {
  return arr[index];
}

function pushItemArray<T>(arr: T[], item: T): void {
  arr.push(item);
}

const techStack = ['js', 'react'];
const nums = [1, 2, 3, 4];

getItemArray(techStack, 0); // 'js'
pushItemArray<string>(techStack, 'ts'); // ['js', 'react', 'ts']

// pushItemArray<number>(techStack, 123); // Error

getItemArray(nums, 0); // 1
pushItemArray(nums, 5); // [1, 2, 3, 4, 5];
  • 제네릭 타입 변수
function printOut<T>(input: T): T {
  console.log(input.length); // Error: T doesn't have .length
  return input;
}
function printOut<T>(input: T[]): T[] {
  console.log(input.length);
  return input;
}

printOut([1, 2, 3]);
  • 제네릭 제약 조건
function printOut<T>(input: T): T {
  console.log(input.length); // Error: T doesn't have .length
  return input;
}
interface LengthWise {
  length: number;
}

function printOut<T extends LengthWise>(input: T): T {
  console.log(input.length);
  return input;
}

// printOut(10); // Error, 숫자 타입에는 `length`가 존재하지 않으므로 오류 발생
// printOut({ length: 0, value: 'hi' }); // `input.length` 코드는 객체의 속성 접근과 같이 동작하므로 오류 없음

타입 추론

  • 기본 타입 추론
let a = 123;
let b = 'abc';

a = 'abc';
b = 123;

const c1 = 123;
const c2 = 'abc';

const arr = [1, 2, 3];
const [n1, n2, n3] = arr;
arr.push('a');

const obj = { numId: 1, stringId: '1' };
const { numId, stringId } = obj;
console.log(numId === stringId);
  • 함수 타입 추론
const func1 = (a = 'a', b = 1) => {
  return `${a} ${b};`;
};
func1(3, 6);

const v1: number = func1('a', 1);

const func2 = (value: number) => {
  if (value < 10) {
    return value;
  } else {
    return `${value} is big`;
  }
};
profile
취준 개발자

0개의 댓글