youngst
Young St_____
youngst
  • 분류 전체보기 (30)
    • Dev (28)
      • JS Family, HTML, CSS (14)
      • Git & Github (0)
      • Projects (7)
      • else (5)
      • TIL (2)
    • 일상 (2)
      • 그냥 글 (1)
      • 사과 농장에서 살아남기 (1)

인기 글

태그

  • CloneCoding
  • JavaScript
  • 프론트엔드스쿨
  • JSEvent
  • vscode
  • 후기
  • Firebase
  • jsdoc
  • 옥소폴리틱스
  • Vite
  • 공부내용정리
  • TypeScript
  • 제로베이스
  • GitHub-Page
  • ReactRouter
  • Next.js
  • 제로베이스스쿨
  • React
  • react-router
  • styled-components

티스토리

hELLO · Designed By 정상우.
youngst

Young St_____

Dev/JS Family, HTML, CSS

[TypeScript] 타입스크립트 입문(3) - 인터페이스, 타입 가드, 열거형, 유니온 타입

2022. 9. 12. 12:22

타입스크립트의 고유 기능들

인터페이스

  • JavaScript에서는 존재하지 않는다.
  • 객체의 타입을 정의하고 생김새를 가지도록 할 수 있다.
  • TypeScript에서의 클래스 기능은 C#에서 유래된 것이 많다.
  • 일부 기능은 TS에서만 존재하는 고유 문법으로 컴파일 후에 사라진다.
  • extends가 아닌 implements 키워드로 구현한다.
/**
 * 인터페이스
 * 
 * interface 
 * - 정의
 * - 설계
 * 
 * implements
 * - 구현
 */
interface Person {
  name: string
  age: number
}

const jang: Person = {
  name: 'Jang',
  age: 99
}

 

implements

  • interface의 설계를 구현한다
/**
 * interface implements
 */
interface Animal {
  name: string
  run(): string
}

interface Person {
  sayName(): string
}

class AnyClass {
}

//여러 개를 implement 가능, 클래스 확장도 가능
class Jang extends AnyClass implements Animal, Person {
  constructor(public name: string) {
    super()
  }

  run() {
    return this.name
  }

  sayName() {
    return `사람의 이름은 ${this.name}`
  }
}

 

extends

  • 인터페이스끼리 확장 가능 - 충돌 주의!
/**
 * interface extends
 */
interface Animal {
  name: string
  run(): string
}

//인터페이스끼리도 확장 가능 - 충돌 주의!
interface Person extends Animal {
  sayName(): string
}

const jang: Person = {
  name: 'Jang',
  run() {
    return 'string'
  },
  sayName() {
    return 'string2'
  }
}

 

타입 가드

typeof

  • JavaScript에서 이미 존재하는 타입 검사 연산자
  • typeof 연산자는 피연산자의 자료형을 문자열로 반환
/**
 * typeof
 */
function print(value: number | string): string {
  if (typeof value === 'number') {
    return String(value)
  }

  if (typeof value === 'string') {
    return value
  }

  return value
}

 

in

  • JavaScript에서 객체가 특정 속성(Array 등)을 가지고 있는지 검사해 결과를 boolean으로 반환한다.
/**
 * in 연산자
 */
interface Dog {
  name: string
  bark(): '멍멍'
}

interface Cat {
  name: string
  meow(): '냐옹'
}

function sayAnimal(animal: Dog | Cat) {
  if ('bark' in animal) {
    animal.bark()
    animal.name
  }

  if ('meow' in animal) {
    animal.meow()
  }
}

 

instanceof

  • JS에서 이미 존재하는 키워드
  • 생성자의 prototype 속성이 객체의 prototype 체인 어딘가 존재하는지 판별
  • typeof처럼 사용 가능
/**
 * instanceof
 */
function getDate(date: Date | string): Date {
  if (date instanceof Date) {
    return date
  }

  return new Date(date)
}

 

사용자 정의

  • 사용자 정의 타입 가드
  • '매개변수 is 타입' 형태로 사용
/**
 * 사용자 정의 타입 가드
 * 
 * 매개변수 is 타입
 */
function isDate(date: Date | string): date is Date {
  return date instanceof Date
}

function getDate(date: Date | string): Date {
  if (isDate(date)) {
    return date
  }

  return new Date(date)
}

interface Dog {
  name: string
  bark(): '멍멍'
}

interface Cat {
  name: string
  meow(): '냐옹'
}

function isDog(animal: Dog | Cat): animal is Dog {
  return 'bark' in animal
}

function isCat(animal: Dog | Cat): animal is Cat {
  return 'meow' in animal
}

function sayAnimal(animal: Dog | Cat) {
  if (isDog(animal)) {
    animal.bark()
  }

  if (isCat(animal)) {
    animal.meow()
  }
}

 

열거형

  • 의미있는 상수 자료를 정의할 수 있다.(문서화)
  • 키를 값에 할당하며 순서가 없는 집합이자 자료구조이다.
  • enum 키워드 + PascalCase 조합으로 생성한다.
  • 계산된 값을 사용할 수 있다. -> TypeScript가 알아서 추론
  • enum은 컴파일 후에도 JavaScript에 함수형태로 남는다!
/**
 * 열거형 (Enum)
 */
enum Prize {
  Gold = 100,
  Silver, //101
  Bronze  //102
}

interface Inter {
  name: 'name'
}

// console.log(Inter.name)
// console.log(Prize)
console.log(Prize.Gold)
console.log(Prize['Gold'])

 

숫자형 열거

/**
 * 숫자 열거형 (Enum)
 */
enum Prize {
  Gold = 500,
  Silver = 600,
  Bronze = 700,
}

enum Order {
  First = 1,
  Second, //2
  Third,  //3
}

 

문자형 열거

  • 각 멤버의 값은 문자열로 초기화되어야 한다.
  • 숫자형 열거와 동작 방식이 다르다.
    • 값이 자동으로 증가하지 않는다.
    • 이외에 리버스 매핑 가능 여부등의 차이점도 존재한다.
/**
 * 문자 열거형 (Enum)
 */
enum Prize {
  Gold = 'Gold',
  Silver = 'Silver',
  Bronze = 'Bronze',
}

console.log(Prize)
console.log(Prize.Gold)
console.log(Prize['Bronze'])

 

혼합형 열거

/**
 * Heterogeneous 열거형 (혼합)
 * 되긴 되는데 굳이...?
 */
enum Dummy {
  First = 0,
  Silver = 'Silver',
}

enum BoolLikeEnum {
  No = 0,
  Yes = 'YES',
}

 

리버스 매핑

  • 숫자형 열거의 경우 키와 값을 역으로 매핑할 수 있다.
    • 문자형 열거는 지원되지 않음
/**
 * 리버스 매핑 (역방향 찾기)
 */
enum Order {
  // name = value
  First = 1,
  Second = 2,
  Third = 3,
}

const firstVal = Order.First
const keyOfFirstVal = Order[firstVal]

console.log(firstVal)
console.log(keyOfFirstVal)

// enum OrderStr {
//   First = 'First',
//   Second = 'Second',
//   Third = 'Third',
// }

// console.log(Order)
// console.log(OrderStr)

 

const 열거

  • 기본적으로 열거형은 불안전한 접근을 허용한다.
  • const enum은 이러한 점을 보완하기 위한 안전한 열거형이다.
  • enum 앞에 const 키워드를 명시하여 사용
  • 컴파일 후 제거되기 때문에 enum과 달리 JavaScript 코드를 생성하지 않는다.
/**
 * const 열거
 */
const enum Desk {
    Color = 'White',
    Width = 1400,
}

Desk.Color
// Desk.Height 
// Desk['Height'] //const 없을 시 다른 에러 발생!(cannot find name 'Height') -> 불안전한 접근

 

열거형 활용

  • 열거형은 런타임에 존재하는 실제 객체
  • keyof, keyof typeof 와 조합하여 활용할 수 있다.
/**
 * 열거형 활용
 */
const enum Language {
    TypeScript = 'TS',
    JavaScript = 'JS',
    Java = 'JAVA',
    Ruby = 'RB',
}

const Language2 = {
    TypeScript: 'TS',
    JavaScript: 'JS',
    Java: 'JAVA',
    Ruby: 'RB',
} as const //read only

type LangCode = keyof typeof Language
// 위와 아래가 같다
type LangCode2 = "TypeScript" | "JavaScript" | "Java" | "Ruby"

function getLang(langCode: LangCode) {
    console.log(langCode)
}

 

논리 연산자 활용 타입

타입 별칭

  • 의미없는 반복을 줄이고 타입을 명시적으로 사용하도록 돕는다.
  • let, const를 선언해 변수를 초기화 하듯 사용할 수 있다!
  • 컴파일러가 따로 추론하지는 않는다(인터페이스와의 차이점)
/**
 * Type Aliases (타입 별칭)
 */
type str = string
type num = number
type arr = num[]
type func = () => void

type Person = {
  name: str
  age: num
  counts: arr
  getInfo: func
}

//인터페이스는 타입 추론 등 다양한 기능이 있다
interface PersonInterface {
  name: str
  age: num
  counts: arr
}

 

Union Type

  • 둘 중 하나(or 연산)
  • 아주 유용하다!
/**
 * Union 타입 (합집합)
 */
type StringOrNumber = string | number
type GenderType = 'M' | 'F'

const a:StringOrNumber = 'STR'
const b:StringOrNumber = 123
// const c:StringOrNumber = boolean

type Person = {
  name: string
  age: number
}

type Me = {
  name: string
  genderType: GenderType
}

const obj: Person | Me = {
  name: 'Jang',
  age: 99,
  genderType: 'M'
}

 

Intersection Type

  • 두 타입의 공통(교집합)
  • 잘은 안 쓴다..
/**
 * Intersection 타입 (교집합)
 * - 둘의 공통 분모
 * - 잘은 안 씀..
 */
type StringAndNumber = string & number
type GenderType = 'M' | 'F'

// const a:StringAndNumber = 'STR'
// const b:StringAndNumber = 123
// const c:StringAndNumber = boolean

type Person = {
  name: string
  age: number
}

type Me = {
  name: string
  generType: GenderType
}

const obj: Person & Me = {
  name: 'Jang',
  age: 99,
  generType: 'M' //하나라도 없으면 에러 발생!
}

 

유니온 타입 판별

  • 추론하기 어려운 유니온 타입을 추론하기 위함
  • 적절한 타입 가드 사용
  • 무분별한 유니온 타입 사용 지양
/**
 * 유니온 타입 판별
 */
interface Male {
  name: string
  age: number
  genderType: 'M'
}

interface Female {
  name: string
  age: number
  genderType: 'F'
}

type Person = Male | Female

function createMale({ name, age, genderType }: Person): Male {
  return {
    name, age, genderType
  }
}

function createFemale({ name, age, genderType }: Person): Female {
  return {
    name, age, genderType
  }
}

 

 

 

저작자표시 비영리 변경금지 (새창열림)

'Dev > JS Family, HTML, CSS' 카테고리의 다른 글

[React] 리액트 심화 - SPA, React Router, 비동기 프로그래밍  (0) 2022.09.16
[TypeScript] 타입스크립트 입문 (4) - 제네릭, 고급 타입 다루기  (5) 2022.09.14
[TypeScript] 타입스크립트 입문 (2) - 기본 타입, 클래스  (0) 2022.09.09
[TypeScript] 타입스크립트 입문(1)  (2) 2022.09.04
[React] 일주일만에 리액트 정복하기! (2)  (0) 2022.08.03
    'Dev/JS Family, HTML, CSS' 카테고리의 다른 글
    • [React] 리액트 심화 - SPA, React Router, 비동기 프로그래밍
    • [TypeScript] 타입스크립트 입문 (4) - 제네릭, 고급 타입 다루기
    • [TypeScript] 타입스크립트 입문 (2) - 기본 타입, 클래스
    • [TypeScript] 타입스크립트 입문(1)
    youngst
    youngst
    좋은 프론트엔드 개발자가 되고 싶습니다

    티스토리툴바