📁
til
  • TIL(Today I Learned)
  • javascript
    • value-number-string-boolean-null-undefined
    • primitive-reference
    • Hoisting
    • Prototypes in Javascript
    • this
    • prototype
    • 콜백함수 (Callback function)
    • 함수의 호출
    • 자료구조 new keyword
    • closure
    • Promise
    • event-loop
    • array-object
    • 객체
    • Arguments
    • higher order function
    • operators-function-control-flow
    • 객체 생성 패턴 3가지
    • Javascript scopes
    • Functional Programming
    • Design Patterns
    • 데이터 타입
    • Object 객체
    • 표준 내장 객체의 확장
    • 참조
    • 함수
    • 상속(Inheritance)
    • this - 'this'를 사용하는 해당 함수를 '어떻게' 실행하느냐에 따른 4가지 this 정의
    • 전역객체(Global object)
    • 객체 지향 프로그래밍
    • The 'new' keyword - Object Creation in JavaScript
  • javascript-api
    • Number
      • Number.MAX_VALUE
      • Number.isInteger
      • Number.NEGATIVE_INFINITY
      • Number.isNaN()
      • Number.POSITIVE_INFINITY
      • Number.parseFloat
      • Number.EPSILON
      • number.toExponential
      • Number.MAX_SAFE_INTEGER
      • Number1 - 자연수, 정수, 10진수, 2진수, 부동소수점, 실수
      • Number.isSafeInteger()
      • Number.MIN_VALUE
      • Number.parseInt
      • Number.NaN
      • Number.isFinite()
      • Number.MIN_SAFE_INTEGER
      • toFixed
    • string.split
    • String.fromCodePoint
    • string.trimEnd
    • string.padStart
    • string.@@iterator
    • String.fromCharCode
    • string.toUpperCase
    • string.codePointAt
    • string.toLowerCase()
    • string.toString
    • string.includes
    • string.replace()
    • string.charAt
    • String.lastIndexOf
    • string.slice
    • string.search
    • string.padEnd
    • string.substring
    • string.length
    • string.trim
    • string.localeCompare
    • String.indexOf
    • string.endsWith
    • string.valueOf
    • String.raw
    • string.matchAll()
    • string.repeat
    • string.match
    • String.prototype
    • string.startsWith
    • string.charCodeAt
    • string.trimStart
    • string.concat
    • string.toLocaleUpperCase()
    • string.toLocaleLowerCase
    • String
  • learn-node
    • debugger
    • Tip
  • schema-design
    • Database Schema Design
    • Database Schema Design
  • react
    • LifeCycle
    • redux
    • Context API
    • 함수형 컴포넌트와 클래스, 어떤 차이가 존재할까?
    • Hooks과 useEffect 사용해 보기
    • Route
    • async wait 사용하기
    • Hooks API Reference
    • context
    • npm uninstall 하는법
    • test 만들기
  • tip
    • 클린코드
    • BxSlider로 텍스트 흐르는 효과 만들기
  • javascript30
    • Event Capture, Propagation, Bubbling and Once
    • Object and Arrays - Reference VS Copy
  • typescript
    • 우아한 타입스크립트 2부
    • The Basic Cheatsheet
    • TypeScript
    • Type Guards and Differnetiating Types
    • 우아한 타입스크립트
    • Generics
  • git-from-the-hell
    • git
    • init-status-add-commit-log-stage-repository
    • log-diff
    • 머지 후 branch 삭제하기
    • 지옥에서 온 Git
    • reset-revert
    • develop branch 를 pull 하고 싶을때
  • conference-and-seminar
    • 모던 프론트엔드 개발환경의 이해
  • fire-base
    • Firebase .gitignore
  • vanillacoding
    • Data Structures
    • Sorting Algorithms - part 1
    • Promise
    • class
    • 04.quiz
    • 07.event-loop
    • Design Patterns
    • OOP (Object Oriented Programming)
  • etc
    • 알고리즘 코드리뷰
    • 스스로 공부하는 법
    • 바닐라코딩 수강 후기
    • async 과제 후기 - 비동기, 동기, 클로저, 배열과 객체
    • 유용한 사이트
  • algorithm
    • The Supermarket Queue
    • Find the odd int
    • The Office III - Broken Photocopier
    • Directions Reduction
    • The Office II - Boredom Score
    • Divisible Sum Pairs
    • Codewars 이용자 솔루션 모음
    • Shortest Word
    • find key
    • Two Sum
    • Simple Pig Latin
  • Book
    • the essence of object-orientation
      • 타입과 추상화
      • 객체 지도
      • 이상한 나라의 객체
      • 추상화 기법
      • 05. 책임과 메시지
      • 07.함께 모으기
      • 04. 역할, 책임, 협력
      • 협력하는 객체들의 공동체
  • ecma-script2015
    • Object Literal Upgrades
    • default-parameter-template-literals-arrow-functions
    • spread-operator-rest-param
    • let-const-rest-parameter-spread-operator-destructuring
  • http
    • 웹 브라우저에 URL을 입력했을 때 어떻게 웹 페이지가 보여질까?
  • jest
    • toThrow(error?)
  • data-structures
    • Data Structures
  • express
    • express generator
    • CORS
  • css-flexible-box-layout
    • flex 해버렸지 뭐야
  • git
    • Git
  • mongodb
    • MongoDB
  • markdown
    • use-markdown
  • cmder
    • cmd 명령어 모음
  • debug
    • trackClicksEx function error
  • npm
    • NPM TOKEN 설정하기
  • storybook
    • Storybook
  • sort
    • Sorting Algorithms - part 1
  • javascript-koans
    • Javascript Koans 오답노트
  • rxjs
    • Rx.js
  • dom-elements
    • HTML Element
  • redux-toolkit
    • Redux Toolkit
  • github-actions
    • GitHub Actions
  • redux-middleware
    • redux middleware
  • rest
    • rest
  • css-rendering
    • 코드 스피츠 - CSS Rendering 1회차 2/2
    • 코드 스피츠 - CSS Rendering 1회차 1/2
  • you-dont-know-js
    • 타입
  • server
    • # shutdown local server
  • semantic-versioning
    • Semantic Versioning 2.0.0
Powered by GitBook
On this page
  • 실전 타입스크립트 코드 작성하기
  • 1. Conditional Type을 활용하기
  • Item<T> - T에 따라 달라지는 contatiner
  • T가 string이면 StringContainer, 아니면 NumberContainer
  • Item<T> T가 string 이면 StringContainer, T가 number 면 NumberContainer 아니면 사용 불가
  • ArrayFilter<T>
  • Table or Dino
  • Flatten<T>
  • infer
  • 함수의 리턴 타입 알아내기 - MyReturnType
  • 내장 conditional types (1)
  • 내장 conditinal types (2)
  • 내장 conditional types (3)
  • Function 인 프로퍼티 찾기
  • 2. Overloading을 활용하기
  • 오버로딩이 불가능한 자바스크립트에 타입을 붙이는 경우

Was this helpful?

  1. typescript

우아한 타입스크립트 2부

실전 타입스크립트 코드 작성하기

  1. Conditional Type을 활용하기

  2. Overloading을 활용하기

  3. readonly, as const를 남발하기

  4. optional type보단 Union type을 사용하기

  5. never 활용하기

1. Conditional Type을 활용하기

Item<T> - T에 따라 달라지는 contatiner

interface StringContainer {
  value: string;
  format(): string;
  split(): string[];
}

interface NumberContainer {
  value: number;
  nearestPrime: number;
  round(): number;
}

type Item1<T> = {
  id: T,
  container: any;
}

const item1: Item1<string> = {
  id: 'aaaaaa',
  container: null,
}

조건부로 할 수 있다.

T가 string이면 StringContainer, 아니면 NumberContainer

type Item2<T> = {
  id: T; 
  // T가 string이면? 
  container: T extends string ? StringContainer : NumberContainer;
}

const item2: Item2<string> = {
  id: 'aaaaaa',
  container: null, // Type 'null' is not assignable to type 'StringContainer'.
}

Item<T> T가 string 이면 StringContainer, T가 number 면 NumberContainer 아니면 사용 불가

type Item3<T> = {
  id: T extends string | number ? T : never;
  container: T extends string ? StringContainer : T extends number ? Number Conainer : never;
}

const item3: Item3<boolean> = {
  id: true, // Type 'boolean' is not assignable to type 'never'.
  container: null, // Type 'null' is not assignable to type 'neber'.
}

어떤 값도 넣을 수 없는게 never라고 볼 수 있다.

ArrayFilter<T>

// T가 Array 형태면 T를 반환 아니면 never를 반환
type ArrayF ilter<T> = T extends any[] ? T : never;
type StringsOrNumbers = ArrayFilter<string | number | string[] | number ]\>;

Table or Dino

interface Table {
  id: string;
  chairs: string[];
}

interface Dino {
  id: number;
  legs: number;
}

interface World {
  // string과 number를 제약하는 방법
  getItem<T extends string | number>(id: T): T extends string ? Table : Dino;
}

let world: World = null as any;

const dino = world.getItem(10);
const what = world.getItem(true); // Error! Argument of type 'boolean' is not assignable parameter of type 'string | number'

Flatten<T>

type Flatten<T> = T extends any [] ? T[number] : T extends object ? T[keyof T] : T;

const numbers = [1, 2, 3];
type NumbersArrayFlattened = Flatten<typeof numbers>;
// 1. numer[]
// 2. number

const person = {
  name: 'Mark',
  age: 38
}

type SomeObjectFlattened = Flatten<typeof person>;
// 1. keyof T -> 'name' | 'age' 
// 2. T['name' | 'age']  -> T['name'] | T['age'] -> string | number

const isMale = true;
type SomeBooleanFlattened =  Flatten<typeof isMale>;

infer

// infer k -> k를 추론한다.
type UnpackPromise<T> = T extends Promise<infer k>[] ? K : any;
const promise = [Promise.resolve('Mark'), Promise.resolve(38)];

type Expected = UnpackPromise<typeof promises>; // string | number;

함수의 리턴 타입 알아내기 - MyReturnType

function plus1(seed: number): number {
  return seed + 1;
}

// <T extends (...args: any) => any> -> 함수여야 한다는 제약사항이다. 
// 함수이면 리턴타입을 R로 추론해서 사용하겠다. 
type MyReturnType<T extends (...args: any) => any> => T extends (
    ...args: any) => inter R ? R : any;
)

// <typeof plus1> 는 함수를 넣은 것
// 제약사항이 함수인데 함수니까 통과가 됐다.
// inter R 리턴타입을 추론하겠다. -> number
type Id = MyReturnType<typeof plus1>;

lookupEntity(plus1(10));

// 직접 number인지 string인지 추론하는게 아니라 직접 타입으로 추론해서 넣는 방식
function lookupEntity(id: Id) {
  // query DB for entity by ID
}

소스코드를 보고 타입을 알아낸 다음 타입이 맞는지를 확인하는 과정을 거친다. 와우

내장 conditional types (1)

// type Exclude<T, U> = T extends U ? never : T;
// string을 제외한 것을 얻고 싶을 때
type Excluded = Excluded<string | number, string>; // number - diff

// type Extract<T, U> = T extends U ? T : never;
type Extracted = Extract<string | number, string>; // string - filter

// Pick<T, Exclude<keyof T, K>>; (Mapped Type)
type Picked = Pick<{name: string, age: number}, 'name'>;

// type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
type Omited = Omit<{name: string, age: number}, 'name'>;

// type NonNullable<T> = T extends null | nudefined ? never : T;
// <string | number | null | undefined> -> string | number | never | never
type NonNullabled = NonNullable<string | number | null | undefined>;

내장 conditinal types (2)

/*
함수라는 제약 사항 <T extends (...args: any) => any> 
type Parameters<T extends (...args: any) => any> = T extends (
 ...args: infer P
) => any ? P : never;
*/
// parameters의 타입만 뽑아낼 수 있다.
type MyParameters = Parameters<(name: string, age: number) => void>; // [name: string, age: number]

내장 conditional types (3)

interface Constructor {
  new (name: string, age: number): string;
}

/*
type Parameters<T extends (...args: any) => any> = T extends (
 ...args: infer P
) => any ? P : never;
*/

type MyConstructorParameters = ConstructorParameters<Constructor>; // [name: string, age: number]

/*
type instanceType<T extends new (...args: any) => any> = T extends new (
...args: any) => infer R ? R : any; 
*/

// T의 제약사항이 <T extends new (...args: any) => any> 생성자인데 생성자에서
// 반환값 즉 인스턴스 타입 new (name: string, age: number): string; 
type MyInstanceType = InstanceType<Constructor>; // string

Function 인 프로퍼티 찾기

type FunctionPropertyNames<T> = {
  // never는 지운다. 
  [K in keyof T]: T[K] extends Function? K : never;
}[keyof T];
type FunctionProperties<T> = Pick<T, FunctionPropertyNames<T>>;

type NonFunctionPropertyNames<T> = {
  [K in keyof T]: T[K] extends Function ? never : K;
}
type NonFunctionProperties<T> = Pick<T, NonFunctionPropertyNames<T>>;

interface Person {
  id: number;
  name: string;
  hello(message: string): void;
}

type T1 = FunctionPropertyNames<Person>;
type T2 = NonFunctionPropertyNames<Person>;
type T3 = FunctionProperties<Person>;
type T4 = NonFunctionProperties<Person>;

2. Overloading을 활용하기

오버로딩이 불가능한 자바스크립트에 타입을 붙이는 경우

function shuffle(value: string | any[]) : string | any[] {
  if(typeof value === 'string') {
    return value.split('').sort(() => Math.random() - 0.5).join('');
  }
  return value.sort(() => Math.random() - 0.5);
}

console.log(shuffle('Hello, Mark!')); // string | any[]
console.log(shuffle(['Hello', 'Mark', 'long', 'time', 'no', 'see'])); // string | any[]
console.log(shuffle([1, 2, 3, 4, 5])); // string | any[]
PrevioustypescriptNextThe Basic Cheatsheet

Last updated 4 years ago

Was this helpful?