๐Ÿค”

til[wip]

  • When m1 f***s sharp

      06-09-2021
      brew reinstall vips
    • isReactElement

      • #typescript
      03-19-2021
      const isReactElement = (element: ReactNode): element is ReactElement =>
        element !== null && typeof element === 'object' && 'props' in element;
    • as const

      • #typescript
      01-21-2021
    • Promise.allSettled

      • #javascript
      • #typescript
      10-23-2020

      ๋ชจ๋“  promise๊ฐ€ resolve/reject ๋˜๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€ ๊ฐ promise์˜ result๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

      Promise.all๊ณผ ๋‹ค๋ฅธ์ 

      1. promise ์ค‘ reject๊ฐ€ ์žˆ์–ด๋„ ์ผ๋‹จ ๋ชจ๋‘ pending ์ƒํƒœ๋ฅผ ๋ฒ—์–ด๋‚˜๊ธธ ๊ธฐ๋‹ค๋ ธ๋‹ค๊ฐ€ ๊ฒฐ๊ณผ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
      2. reject๋ฅผ ๋”ฐ๋กœ ํ•˜์ง€ ์•Š๊ณ  ๋ฐ˜ํ™˜๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋ฏ€๋กœ catch๋ฅผ ํƒ€์ง€ ์•Š๋Š”๋‹ค.
      3. ๋Œ€์‹  ๋ฐ˜ํ™˜ ๊ฒฐ๊ณผ๊ฐ’์ด ๋ณดํ†ต์˜ promise์™€ ๋‹ค๋ฅด๋‹ค. Promise<T>๊ฐ€ ์•„๋‹ˆ๊ณ  PromiseSettledResult<T>๋ฅผ ๋ฐ˜ํ™˜.
      4. PromiseSettledResult๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์ƒ๊ฒผ๋‹ค.
      // fullfiled
      {
        status: "fullfiled",
        value: T
      }
      
      // rejected
      {
        status: "rejected",
        reason: any
      }

      ์‹ค์ œ๋กœ ๋Œ๋ ค๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

      Screen Shot 2020-10-23 at 12 04 57 PM
      Playground

      Ref

      Promise.allSettled

    • conditional spread

      • #javascript
      10-08-2020
      const cond = false;
      const arr = [
        ...(cond ? ['a'] : []),
        'b',
      ];
          // ['b']

      https://2ality.com/2017/04/conditional-literal-entries.html

    • chrome ์—์„œ command palette ์‚ฌ์šฉํ•˜๊ธฐ

      • #chrome
      09-09-2020
      shift + cmd + /
      

      ์ด๊ฒƒ์€ ์‚ฌ์‹ค Help/Search ๋‹จ์ถ•ํ‚ค์ด์ง€๋งŒ vscode์˜ shift + cmd + p ์™€ ๊ฐ™์€ ์šฉ๋„๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

    • chrome devtools device toolbar responsive mode ์—์„œ ๋งˆ์šฐ์Šค ํฌ์ธํ„ฐ ์‚ฌ์šฉํ•˜๊ธฐ

      • #chrome_devtools
      08-14-2020

      Step 1

      Screen Shot 2020-08-14 at 9 42 28 AM

      Step 2

      Screen Shot 2020-08-14 at 9 41 55 AM

      Step 3

      Screen Shot 2020-08-14 at 9 43 54 AM

      Done!

      Screen Shot 2020-08-14 at 9 52 06 AM

    • Get list of globally installed packages

      • #npm
      • #yarn
      08-04-2020

      npm:

      npm list -g --depth 0

      yarn:

      yarn global list --depth 0
    • fix firefox color render

      • #color
      • #firefox
      07-27-2020

      ?

      firefox์˜ ์ปฌ๋Ÿฌ๊ฐ€ ๋ญ”๊ฐ€ ์ข€ ๋” ์ฑ„๋„๊ฐ€ ๋†’๊ฒŒ ๋ Œ๋”๋ง ๋˜๋Š” ๊ฒฝํ–ฅ์ด ์žˆ๋‹ค.

      1. chrome

      Screen Shot 2020-07-27 at 4 00 39 PM

      1. safari

      Screen Shot 2020-07-27 at 4 01 59 PM

      1. firefox

      Screen Shot 2020-07-27 at 4 03 52 PM

      ์š”๊ฑธ ์—†์• ๋ ค๋ฉด?

      !

      1. ์ผ๋‹จ firefox์˜ ์ฃผ์†Œ์ฐฝ์— about:config๋ฅผ ์ž…๋ ฅํ•ด ์‹ ๋น„์˜ ์„ธ๊ณ„๋กœ ๋“ค์–ด๊ฐ€์„œ,
      2. ์‹ ๋น„์˜ ์„ธ๊ณ„ ๊ฒ€์ƒ‰์ฐฝ์— color_management๋ฅผ ์ณ๋ณด๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ์„ค์ •๊ฐ’๋“ค์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ด์ค‘์—์„œ,
        Screen Shot 2020-07-27 at 4 16 53 PM
      3. gfx.color_management.mode๋ฅผ 1๋กœ ๋ฐ”๊พผ๋‹ค.
      4. gfx.color_management.enablev4๋ฅผ true๋กœ ๋ฐ”๊พผ๋‹ค.
      5. ์จ˜
        Screen Shot 2020-07-27 at 4 19 46 PM

      ์ด๊ฒƒ๋“ค์ด ๋ญ๋ƒ?

      1. gfx.color_management.mode:
        • 0: Color management disabled.
        • 1: Full color management.
        • 2: Color management applied only to tagged images.
      2. gfx.color_management.enablev4:
        • ์ฐพ๋Š” ์ค‘

      Refs

    • google fonts์—์„œ ํŠน์ • ์บ๋ฆญํ„ฐ๋งŒ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ

      • #css
      • #google_fonts
      07-20-2020

      google fonts๋ฅผ url๋กœ ๋ถˆ๋Ÿฌ์˜ค๋Š” ๋ฐฉ์‹์œผ๋กœ ์‚ฌ์šฉ์‹œ unicode-range๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.
      query string ์˜ต์…˜์œผ๋กœ subset ํ˜น์€ text๋ฅผ ์ค„ ์ˆ˜ ์žˆ๋‹ค.

      subset

      subset์€ ์–ธ์–ด ๊ธฐ์ค€์œผ๋กœ, ์˜๋ฌธ์—๋งŒ ํŠน์ • ํฐํŠธ๋ฅผ ์ ์šฉํ•˜๊ณ  ์‹ถ์„ ๊ฒฝ์šฐ ์‚ฌ์šฉํ•œ๋‹ค. Roboto๋ฅผ ์˜๋ฌธ๊ณผ ์ˆซ์ž์—๋งŒ ์“ฐ๊ณ  ์‹ถ๋‹ค๋ฉด?
      https://fonts.googleapis.com/css2?family=Roboto&subset=latin ์ด๋ผ๊ณ  ํ•˜๋ฉด ๋œ๋‹ค.

      text

      text๊ฐ€ ์ข€ ๋” ์žฌ๋ฐŒ๋Š”๋ฐ, ๊ฐœ๋ณ„ ์บ๋ฆญํ„ฐ๋ฅผ ์˜ต์…˜์œผ๋กœ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด Roboto๋ฅผ 0๊ณผ 1์—๋งŒ ์“ฐ๊ณ  ์‹ถ๋‹ค๋ฉด?

      https://fonts.googleapis.com/css2?family=Roboto&text=01 ์œผ๋กœ ์š”์ฒญํ•˜๋ฉด ๋œ๋‹ค.

    • sourceViewController -> source

      • #swift
      07-06-2020

      Implement Navigation์„ ์ง„ํ–‰ํ•˜๋‹ค๊ฐ€ ์•„๋ž˜ ์›Œ๋‹์„ ๋งŒ๋‚ฌ๋‹ค.

      Screen Shot 2020-07-07 at 6 32 27

          //MARK: Actions
          @IBAction func unwindToMealList(sender: UIStoryboardSegue) {
      -        if let sourceViewContoller = sender.sourceViewController as? MealViewController, let meal = sourceViewContoller.meal {
      +        if let sourceViewContoller = sender.source as? MealViewController, let meal = sourceViewContoller.meal {
                  // Add new meal.
                  let newIndexPath = IndexPath(row: meals.count, section: 0)
                  meals.append(meal)
                  tableView.insertRows(at: [newIndexPath], with: .automatic)
              }
          }
    • IB?

      • #i_os
      • #swift
      06-29-2020

      Interface Builder

    • Xcode ํ”„๋กœ์ ํŠธ์˜ Team์„ ๋ฐ”๊พธ๋ ค๋ฉด

      • #apple
      • #xcode
      06-27-2020

      ์• ํ”Œ ๋””๋ฒจ๋กœํผ ํ”„๋กœ๊ทธ๋žจ์— ๊ธฐ์กด xcode์— ๋“ฑ๋ก๋˜์–ด์žˆ๋˜ ๊ฒƒ๊ณผ ๋‹ค๋ฅธ apple id๋ฅผ ์‚ฌ์šฉํ•˜๊ฒŒ ๋˜์–ด, ๋“ฑ๋ก๋˜์–ด์žˆ๋˜ Team์„ ๋ฐ”๊ฟ€ ์ผ์ด ์ƒ๊ฒจ์„œ ์•Œ์•„๋ณด์•˜๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด ๊ฐ„๋‹จํ•˜๊ฒŒ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์—ˆ์Œ.

      Screen Shot 2020-06-27 at 20 02 47

    • DFS

      • #algo
      • #data_structures
      • #graph
      06-27-2020
    • stash a folder

      • #git
      06-06-2021
      git stash push [-u] -- <folder>
    • backdrop-filter on Safari

      • #css
      03-18-2021

      make sure your opacity value is 1.

    • type predicate

      • #typescript
      01-11-2021
      interface Article {
         title: string;
         body: string;
      }
      
      function isArticle(body: unknown): body is Article {
        let b = body as Article;
        return !!b && typeof b.body === 'string' && typeof b.title === 'string';
      }
    • cherry-pick range of commits

      • #git
      10-20-2020
      git cherry-pick <SHA>^..<SHA>
    • mobile safari font size issue

      • #safari_is_new_ie
      09-22-2020
      -webkit-text-size-adjust: none;
    • Uncaught TypeError: Cannot read property '__k' of null

      • #preact
      09-09-2020

      preact app์„ ๋ Œ๋”ํ•  DOM el์ด ํ˜„์žฌ ์กด์žฌํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ฐœ์ƒํ•˜๋Š” ์—๋Ÿฌ

    • Unexpected use of 'isNaN'. (eslintno-restricted-globals), Argument of type 'string' is not assignable to parameter of type 'number'. ts(2345)

      • #eslint
      • #typescript
      08-14-2020
      let val = '123'
      
      isNaN(val) // nah! Argument of type 'string' is not assignable to parameter of type 'number'. ts(2345)
      isNaN(123) // nah! Unexpected use of 'isNaN'. (eslintno-restricted-globals)

      then use

      Number.isNaN(val) // yay!
    • "Type aliases can only be used in TypeScript files.ts(8008)" in .js files

      • #flow
      • #vscode
      08-03-2020

      vscode๊ฐ€ flow type ์ •์˜์— .ts๊ฐ€ ์•„๋‹Œ๋ฐ ํƒ€์ž… ๋จธ์‹œ๊ธฐ๊ฐ€ ์žˆ๋‹ค๊ณ  ๊น์น˜๋Š” ์—๋Ÿฌ. settings.json์— ์•„๋ž˜๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

        "javascript.validate.enable": false
    • fix eslint no-undef errors by jest globs

      • #eslint
      07-24-2020

      ?

      Screen Shot 2020-07-24 at 7 26 12 PM

      !

      // .eslintrc.js
      ...
      env: {
        jest: true
      }
      ...
    • Warning: Cannot update a component (*) while rendering a different component (*).

      • #react
      07-14-2020

      setState์—์„œ ๋‹ค๋ฅธ ์ปดํฌ๋„ŒํŠธ์˜ setState๋ฅผ ํ˜ธ์ถœํ•  ๊ฒฝ์šฐ ๋œจ๋Š” ๊ฒฝ๊ณ  ๋ฉ”์‹œ์ง€๋กœ, 16.13.0์—์„œ ์ถ”๊ฐ€๋˜์—ˆ๋‹ค. prop์œผ๋กœ ๋„˜์–ด์˜จ ํ•จ์ˆ˜๊ฐ€ setState๋ฅผ ํ•˜๋Š” ๊ฒฝ์šฐ์— ๋ฐœ์ƒํ•œ๋‹ค.

      ํ•ด๋‹น ์ผ€์ด์Šค๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด, ํ˜ธ์ถœํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ์—์„œ useEffect๋กœ ๊ฐ์‹ธ๋ผ๊ณ  ๊ณต์‹ ์‚ฌ์ดํŠธ์—์„œ ์•ˆ๋‚ดํ•ด์ฃผ๊ณ  ์žˆ๋‹ค.

    • "Could not insert new outlet connection" error

      • #swift
      • #xcode
      07-05-2020

      ๋ฌธ์ œ

      FoodTracker๋ฅผ ์‹ ๋‚˜๊ฒŒ ๋งŒ๋“œ๋Š” ์ค‘์ด์—ˆ๋Š”๋ฐ, save ๋ฒ„ํŠผ์„ MealViewController์— ์—ฐ๊ฒฐ์‹œํ‚ค๋ ค๋˜ ์ˆœ๊ฐ„!

      ์œ„์™€ ๊ฐ™์€ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด์—ฌ์ฃผ๋ฉด์„œ ์•ˆ๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์ƒ๊ฒผ๋‹ค.

      ํ•ด๊ฒฐ

      1. cmd+shift+K๋ฅผ ๋ˆŒ๋Ÿฌ product๋ฅผ clean ํ•œ๋‹ค.
      2. cmd+R๋กœ build + run์„ ํ•œ๋‹ค.
      3. ํ•œ ๋ฒˆ ํ•ด๋ณธ๋‹ค.
      4. ์•ˆ๋˜๋ฉด xcode๋ฅผ ์žฌ์‹œ์ž‘ํ•œ๋‹ค.
    • UIImagePickerControllerOriginalImage

      • #i_os
      • #swift
      06-29-2020

      FoodTracker ์˜ˆ์ œ ์ค‘ Work with View Controllers ํŠœํ† ๋ฆฌ์–ผ์— ๋ฒ„๊ทธ... ๋Š” ์•„๋‹ˆ๊ณ  ์˜›๋‚  ์ž๋ฃŒ๋ผ์„œ ์ง€๊ธˆ ์•ˆ๋Œ์•„๊ฐ€๋Š” ๊ฒŒ ์žˆ์—ˆ๋‹ค.

      ์š” ๋งํฌ๋ฅผ ์ฐพ์•„ ์•„๋ž˜์™€ ๊ฐ™์ด ํ•ด๊ฒฐ

          func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
      
              // The info dictionary may contain multiple representations of the image. You want to use the original.
      -        guard let selectedImage = info[UIImagePickerControllerOriginalImage] as? UIImage else {
      +        guard let selectedImage = info[.originalImage] as? UIImage else {
                  fatalError("Expected a dictionary containing as image, but was provided the following: \(info)")
              }
      
              // Set photoImageView to display the selected image.
              photoImageView.image = selectedImage
      
              // Dismiss the picker.
              dismiss(animated: true, completion: nil)
          }
    • rebase๋ฅผ ํ•˜๋‹ค๊ฐ€ ์ด๊ฑด ์•„๋‹ˆ๋‹ค ์‹ถ์œผ๋ฉด

      • #git
      06-27-2020

      git rebase --abort๋ฅผ ํ•˜๋ฉด ๋œ๋‹ค.

    • ์˜ค๋Š˜๋ถ€ํ„ฐ ์—ฌ๊ธฐ์— ์ž‘์„ฑ

        06-27-2020

        til์„ ์ด์Šˆ๋กœ ์ž‘์„ฑํ•ด๋ณด์ž.

      • yarn upgrade-interactive --latest

        • #yarn
        05-10-2021
        yarn upgrade-interactive --latest
      • warning: could not read '.git/rebase-merge/head-name': No such file or directory

        • #git
        03-17-2021
        git rebase --quit
      • "xcrun: error: active developer path ("/Applications/Xcode.app/Contents/Developer") does not exist"

        • #macos
        12-11-2020
        GHCi, version 8.4.3: http://www.haskell.org/ghc/  :? for help
        xcrun: error: active developer path ("/Applications/Xcode.app/Contents/Developer") does not exist
        Use `sudo xcode-select --switch path/to/Xcode.app` to specify the Xcode that you wish to use for command line developer tools, or use `xcode-select --install` to install the standalone command line developer tools.
        See `man xcode-select` for more details.
        `clang' failed in phase `gcc'. (Exit code: 1)

        โฌ

        sudo xcode-select -switch /Library/Developer/CommandLineTools
      • optional destructurering

        • #javascript
        • #typescript
        10-19-2020
        const { name = {} } = user;
      • list all remote branches

        • #git
        09-22-2020
        git branch -a
      • css grid border collapse (sort of)

        • #css
        08-25-2020

        parent:

        grid-gap: 1px;

        child:

        box-shadow: 0 0 0 1px <color>;
      • vscode์—์„œ preview mode๋กœ ํŒŒ์ผ ์—ด๋ฆฌ์ง€ ์•Š๊ฒŒํ•˜๊ธฐ

        • #vscode
        08-13-2020

        vscode์—์„œ file explorer๋‚˜ search๋ฅผ ํ†ตํ•ด ์ฐพ์€ ํŒŒ์ผ์„ ํด๋ฆญํ•˜๋ฉด ํƒญ์—์„œ italic์œผ๋กœ ํŒŒ์ผ๋ช…์ด ํ‘œ์‹œ๋˜๋ฉด์„œ preview mode๋กœ ์—ด๋ฆฌ๊ณ , ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๋‹ค๋ฅธ ํŒŒ์ผ์„ ์—ด๋ฉด preview mode์˜€๋˜ ํŒŒ์ผ์€ ์‚ฌ๋ผ์ง„๋‹ค. ๋•Œ๋•Œ๋กœ ๊ทธ๋ž˜์„œ ๊ท€์ฐฎ์€ ์ผ์ด ์ƒ๊ธฐ๋Š”๋ฐ, ์ด๊ฒƒ์„ ๋ง‰์œผ๋ ค๋ฉด settings.json์— ์•„๋ž˜๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ๋œ๋‹ค.

        {
          "workbench.editor.enablePreview": false,
        }
      • symlinks

        • #shell
        08-02-2020

        path ์˜ alias ๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ์‰ฝ๋‹ค.

        ln -s /PATH/TO/ORIGINAL /PATH/TO/LINK
      • PR์— PR ๋‚ ๋ฆฌ๊ธฐ

        • #github_cli
        07-23-2020
        gh pr create -R <USER_NAME>/<REPO_NAME> --base <ORIG_PR_BRANCH_NAME>
      • React.memo vs useMemo

        • #react
        07-10-2020

        React.memo

        • Higher order component.
        • prop change๋งŒ์„ ์ฒดํฌํ•จ. ๊ฐ์‹ผ ์ปดํฌ๋„ŒํŠธ ์•ˆ์— useState, useContext๋“ฑ์ด ์žˆ๋‹ค๋ฉด, ์—ญ์‹œ ํ•ด๋‹น state ๋ณ€๊ฒฝ์— ๋”ฐ๋ผ rerender๋จ.

        useMemo

        • Hook.
        • deps array์— ํฌํ•จ๋œ deps๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š์œผ๋ฉด memoized value๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜.
      • How to show code info in Xcode (like vscode)

        • #xcode
        07-03-2020

        option + click

      • vscode๊ฐ€ ํฌ๋งทํŒ… ํ•˜๋ฉด์„œ ์ž๊พธ jsx์— ๋นˆ์นธ์„ ๋„ฃ์œผ๋ฉด

        • #vscode
        06-28-2020

        ์›์ธ

        .jsx ํŒŒ์ผ์˜ File Association์ด Babel JavaScript๋กœ ๋˜์–ด์žˆ์–ด์„œ ์ƒ๊ธฐ๋Š” ๋ฌธ์ œ.

        ํ•ด๊ฒฐ 1

        ํ™”๋ฉด ํ•˜๋‹จ์˜ language mode ์˜์—ญ์„ ํด๋ฆญ -> JavaScript React๋กœ ๋ฐ”๊พธ๋ฉด ํ•ด๊ฒฐ

        Screen Shot 2020-06-28 at 17 52 41

        ํ•ด๊ฒฐ 2

        ๋ฌผ๋ก  settings.json์—์„œ ๋ฐ”๊ฟ€์ˆ˜๋„ ์žˆ๋‹ค.

        "files.associations": {
          "*.jsx": "javascriptreact"
        }
      • ํžˆ์Šคํ† ๋ฆฌ๊ฐ€ ๋‹ค๋ฅธ git repo๋ฅผ ํ•ฉ์น˜๋ ค๋ฉด

        • #git
        06-27-2020

        mergeํ•˜๋ฉด์„œ --allow-unrelated-histories๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

      • show diff of a stash

        • #git
        05-10-2021
        git stash show -p <stash>
      • `mix ecto.create` -> `(Postgrex.Error) FATAL 28000 (invalid_authorization_specification) role "postgres" does not exist`

        • #elixir
        • #phoenix
        03-12-2021
        createuser -s postgres
      • Migrate .re to .res

        • #reason
        • #rescript
        11-20-2020
      • array optional chaining

        • #javascript
        10-14-2020
        optionalArray?.[index]
      • node-sass: "Incompatible units"

        • #node_sass
        09-17-2020
        max(50% - 2px) // sass Error: Incompatible units '%' and 'px'
        calc(max(50% - 2px)) // okay
      • delete all branches except current

        • #git
        08-19-2020
        git branch -D $(git branch)
      • U+001D

        • #html
        • #unicode
        08-06-2020
      • Declaring Global Variables in TypeScript

        • #typescript
        07-31-2020

        daum ์ฃผ์†Œ๊ฒ€์ƒ‰๋“ฑ window์— ๋ญ”๊ฐ€ ๋ผ์›Œ๋„ฃ๋Š” ์™ธ๋ถ€ ๊ธฐ๋Šฅ ์‚ฌ์šฉ์‹œ, window.someApi๋“ฑ์œผ๋กœ ํ˜ธ์ถœํ•˜๊ฒŒ ๋  ๋•Œ๊ฐ€ ์žˆ๋Š”๋ฐ, TS์—์„œ ๋‹น์—ฐํžˆ Property 'someApi' does not exist on type 'Window & typeof globalThis'. ๋ผ๊ณ  ๋ญ๋ผ๊ณ  ํ•œ๋‹ค. ์š”๊ฑธ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋ณดํ†ต์€:

        (window as any).someApi

        ํ˜น์€

        (<any>window).someApi

        ๋ฅผ ์“ฐ๋ผ๊ณ  ํ•˜๋Š”๋ฐ ์•„๋ž˜๊ฐ€ ๋” ๋‚˜์€ ๊ฒƒ ๊ฐ™๋‹ค.

        declare global {
          interface Window {
            someApi: any; // ํ˜น์‹œ ํƒ€์ž… ์ •์˜๋ฅผ ์ œ๊ณตํ•ด์ค€๋‹ค๋ฉด somApiType
          }
        }

        ์š”๊ฒŒ ๋˜๋Š” ๊ฒƒ์€ interface๋Š” merging์ด ๋˜๊ธฐ ๋•Œ๋ฌธ.

        Ref.

        https://mariusschulz.com/blog/declaring-global-variables-in-typescript

      • type argument default value

        • #typescript
        07-23-2020

        ์˜ˆ๋ฅผ ๋“ค์–ด, ์ฒซ๋ฒˆ์งธ arg๋Š” ๋ณดํ†ต string์ด๊ณ  ๋‘๋ฒˆ์งธ arg๋Š” ๋ณดํ†ต number์ธ๋ฐ ์•„๋‹ ์ˆ˜๋„ ์žˆ๊ณ  ๋‘๋ฒˆ์งธ arg๊ฐ€ ์žˆ์„ ์ˆ˜๋„ ์—†์„ ์ˆ˜๋„ ์žˆ๋Š” ํ•จ์ˆ˜์˜ ํƒ€์ž…์„ ์ •์˜ํ•œ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์„ ์–ธํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค.

        type ExampleFn<T, U> = (arg0: T, arg1?: U) => SomeReturnType;

        ๊ทผ๋ฐ ์“ธ ๋•Œ ๋งˆ๋‹ค ์•„๋ž˜์™€ ๊ฐ™์ด ํ•˜๊ธฐ๋Š” ๋งค์šฐ ๊ท€์ฐฎ์€ ์ผ์ด๋‹ค.

        const implmentedFn1: ExampleFn<string, number> = (val: string) => /* ... */

        ๊ทธ๋ž˜์„œ ts๋Š” type argument์—๋„ default value๋ฅผ ์ •ํ•ด๋†“์„ ์ˆ˜ ์žˆ๋Š”๋ฐ, ํ•จ์ˆ˜ default value๋ž‘ ๋™์ผํ•œ ํ˜•ํƒœ๋กœ, ์•„๋ž˜์™€ ๊ฐ™์ด ํ•˜๋ฉด ๋œ๋‹ค.

        type ExampleFn<T = string, U = number> = (arg0: T, arg1?: U) => SomeReturnType;

        ์ด์ œ๋ถ€ํ„ด ๊ตณ์ด ๋ช…์‹œํ•  ํ•„์š”๊ฐ€ ์ƒ๊ธฐ์ง€ ์•Š์œผ๋ฉด ๊ทธ๋ƒฅ ํŽธํ•˜๊ฒŒ ์“ธ ์ˆ˜ ์žˆ๋‹ค.

        const implmentedFn2: ExampleFn = (val: string) => /* ... */

        ๊ทธ๋Ÿฌ๊ณ ๋ณด๋‹ˆ ์•„์˜ˆ arg์— ํƒ€์ž… ์–ด๋…ธํ…Œ์ด์…˜์„ ์•ˆํ•ด๋„ ๋œ๋‹ค.

        const implmentedFn3: ExampleFn = (val) => /* ... */
      • flex

        • #css
        • #flexbox
        07-09-2020

        flex

        flex-grow, flex-shrink, + flex-basis์˜ shorthand์ด๋‹ค.

        syntax

        • One-value syntax:
          the value must be one of:
          • a <number>: In this case it is interpreted as flex: <number> 1 0; the <flex-shrink> value is assumed to be 1 and the <flex-basis> value is assumed to be 0.
          • one of the keywords: none, auto, or initial.
        • Two-value syntax:
          the first value must be a <number> and it is interpreted as <flex-grow>. The second value must be one of:
          • a <number>: then it is interpreted as <flex-shrink>.
          • a valid value for width: then it is interpreted as <flex-basis>.
        • Three-value syntax:
          the values must be in the following order:
          • a <number> for <flex-grow>.
          • a <number> for <flex-shrink>.
          • a valid value for width for <flex-basis>.
      • Create a chrome shorcut to a bookmarklet

        • #chrome
        06-30-2020
      • vscode์—์„œ swift language server ๋Œ๋ฆฌ๊ธฐ

        • #swift
        • #vscode
        06-28-2020

        xcode์—์„  vim key ๋ฐ”์ธ๋”ฉ, hover action ๋“ฑ๋“ฑ์ด ๊ฐ„๋‹จํ•˜๊ฒŒ ์•ˆ๋˜๋Š” ๊ฒƒ ๊ฐ™์•„ vscode์— ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ๊พธ๋ฏธ๋Š” ๊ฒŒ ๊ฐ€๋Šฅํ• ๊นŒ ์•Œ์•„๋ณด์•˜๋‹ค.

        1. ์›ํ•˜๋Š” ์œ„์น˜์— sourcekit-lsp๋ฅผ ํด๋ก  ๋ฐ›๋Š”๋‹ค.
        2. $ cd sourcekit-lst/Editors/vscode
        3. $ npm run createDevPackage
        4. $ code --install-extension out/sourcekit-lsp-vscode-dev.vsix
        5. ๊ณต์‹์—” ์—ฌ๊ธฐ๊นŒ์ง€ ํ•˜๋ฉด ๋œ๋‹ค๊ณ  ๋‚˜์™€์žˆ๊ธด ํ•œ๋ฐ, vscode์—์„œ Starting client failed Launching server using command sourcekit-lsp failed. ๋ผ๋ฉฐ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค.
        6. $ xcrun -f sourcekit-lsp ๋กœ sourcekit-lsp๊ฐ€ ์„ค์น˜๋œ ๊ฒฝ๋กœ๋ฅผ ์•Œ์•„๋‚ด์„œ ๋ณต์‚ฌํ•œ๋‹ค.
        7. vscode settings.json์— ์•„๋ž˜๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.
        8.   "sourcekit-lsp.serverPath": "<๊ฒฝ๋กœ>"
        9. vscode๋ฅผ reload ํ•œ๋‹ค.
        10. ๊ตณ
          Screen Shot 2020-06-28 at 14 34 30
        11. https://marketplace.visualstudio.com/items?itemName=vknabel.vscode-swiftlint ๋„ ์„ค์น˜ํ•˜๋ฉด ์ข‹๋‹ค ์นด๋”๋ผ.
      • blob?

        • #jargon
        06-27-2020

        Is an abbr of Binary Large OBject.

        wikipedia

      • change current directory in vim

        • #vim_nvim_etc
        03-29-2021
        :cd <DIRECTORY>
      • Patch broken node_module with yarn2

        • #yarn_2
        03-10-2021
        1. yarn patch <module>
        2. fix the code inside the generated folder and save it.
        3. yarn patch-commit <generated_folder> > <patch_file_name>.diff
        4. fix package.json with "module": "patch:<module>@<version>#<path_to_patch_file>/<patch_file_name>.diff"
        5. yarn install
      • `Component.displayName`

        • #react
        11-13-2020

        forwardRef๋กœ wrapํ•œ ์ปดํฌ๋„ŒํŠธ์˜ ๊ฒฝ์šฐ devtool์—์„œ ์ปดํฌ๋„ŒํŠธ๋ช…์ด ๋œจ์ง€ ์•Š๋Š”๋‹ค. ๊ทธ๋Ÿด๋•:

        Component.displayName = 'Component'

        ๋กœ ์ผ๋‹จ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

      • Formik's `setFieldValue` returns Promise

        • #formik
        • #typescript
        10-14-2020

        but formik's official type def's wrong

        Screen Shot 2020-10-14 at 2 04 56 PM

        wtf

        Ref

        formium/formik#2059 (comment)

      • alt=""

        • #aria
        • #html
        09-15-2020

        https://developers.google.com/web/fundamentals/accessibility/semantics-builtin/text-alternatives-for-images

        To summarize, all images should have an alt attribute, but they need not all have text. Important images should have descriptive alt text that succinctly describes what the image is, while decorative images should have empty alt attributes โ€” that is, alt="".

      • checkout to prev branch

        • #git
        08-19-2020
        git checkout @{-1}

        ๋” ์งง๊ฒŒ๋Š”

        git checkout -
      • :active on mobile safari

        • #safari_is_new_ie
        08-05-2020
        1. webkit-tap-highlight-color ์“ฐ๊ธฐ -> ๊ทผ๋ฐ :active ๋ž‘ ๋™์ž‘์ด ๋‹ค๋ฆ„

        2. body์— <body ontouchstart=""> ๋„ฃ๊ธฐ

        3. ํ•„์š”ํ•œ ์ปดํฌ๋„ŒํŠธ์— onTouchStart={() => false} ๋„ฃ๊ธฐ

      • merging interfaces

        • #typescript
        07-31-2020
        interface Box {
            height: number;
            width: number;
        }
        
        interface Box {
            scale: number;
        }
        
        let box: Box = {height: 5, width: 6, scale: 10};

        https://www.typescriptlang.org/docs/handbook/declaration-merging.html#merging-interfaces

      • `nvm is not compatible with the npm config "prefix" option: currently set to "/usr/local" Run `npm config delete prefix` or `nvm use --delete-prefix * --silent` to unset it.`

        • #node
        • #nvm
        07-21-2020

        ?

        system์— ์„ค์น˜๋œ node๋ž‘ ์ถฉ๋Œํ•˜๋Š” ๊ฒƒ

        !

        brew uninstall --ignore-dependencies node
      • "String interpolation produces a debug description for an optional value; did you mean to make this explicit?"

        • #deprecated
        • #i_os
        • #swift
        07-08-2020

        Screen Shot 2020-07-08 at 23 06 18

        default:
        -   fatalError("Unexpected Segue identifier; \(segue.identifier)")
        +   fatalError("Unexpected Segue identifier; \(String(describing: segue.identifier))")
      • Header vs Heading

        • #terms
        06-30-2020

        Header: "The upper portion of a page (or other) layout."

        Heading: "The title or topic of a document, article, chapter, or of a section thereof."

        via https://diffsense.com/diff/header/heading

      • Config Github CLI

        • #git
        • #github
        • #github_cli
        06-28-2020
        1. default editor๊ฐ€ nano๋กœ ๋˜์–ด์žˆ์–ด ๋ถˆํŽธํ•˜๋‹ค. vim์œผ๋กœ ๋ฐ”๊พธ๋ ค๋ฉด?

          gh config set editor vim
        2. pr ์‹œ default base๊ฐ€ master๋กœ ๋˜์–ด์žˆ์–ด ๋ถˆํŽธํ•˜๋‹ค. develop์œผ๋กœ ๋ฐ”๊พธ๋ ค๋ฉด?

          gh pr create --base develop

        Reference

      • What's the difference between JSX.Element vs React.ReactNode

        • #react
        • #typescript
        06-27-2020
        • JSX.Element -> Return value of React.createElement
        • React.ReactNode -> Return value of a component

        via React Typescript Cheatsheet

      • kill localhost:PORT

        • #terminal
        03-19-2021
        lsof -iTCP:{PORT} -sTCP:LISTEN
        kill {PID}
      • Beware! Array methods will do shallow copies

        • #javascript
        03-08-2021
        const obj1 = { id: 1, name: "obj1" };
        const obj2 = { id: 2, name: "obj2" };
        const obj3 = { id: 3, name: "obj3" };
        
        const arr = [obj1, obj2, obj3];
        
        const mappedArr = arr.map((obj) => obj);
        const filteredArr = arr.filter((obj) => obj.id !== 3);
        const reducedArr = arr.reduce((acc, item) => {
          if (item.id === 3) {
            return acc;
          }
          return [...acc, item];
        }, []);
        
        const mappedAndSpreadedArr = arr.map((obj) => ({ ...obj }));
        const reducedAndSpreadedArr = arr.reduce((acc, item) => {
          if (item.id === 3) {
            return acc;
          }
          return [...acc, { ...item }];
        }, []);
        
        console.log(obj1 === mappedArr[0]); // true
        console.log(obj1 === mappedAndSpreadedArr[0]); // false
        
        console.log(obj1 === filteredArr[0]); // true
        
        console.log(obj1 === reducedArr[0]); // true
        console.log(obj1 === reducedAndSpreadedArr[0]); // false
        
        const findedObj1 = mappedArr.find((obj) => obj.id === 1);
        findedObj1.name = "lol";
        console.log(obj1.name); // 'lol'
        
        const findedObj2 = mappedAndSpreadedArr.find((obj) => obj.id === 2);
        findedObj2.name = "lol";
        console.log(obj2.name); // 'obj2'
      • remove remote

        • #git
        10-23-2020
        git remote rm <remote-name>
      • img:after

        • #css
        10-10-2020

        ์•ˆ๋จ

        :before๋„ ์•ˆ๋จ

        Ref

        https://stackoverflow.com/a/6949190

      • div border-collapse hack

        • #css
        09-11-2020
        box-shadow:
            <border-width> 0 0 0 <border-color>,
            0 <border-width> 0 0 <border-color>,
            <border-width> <border-width> 0 0 <border-color>,
            <border-width> 0 0 0 <border-color> inset,
            0 <border-width> 0 0 <border-color> inset;

        Ref

        https://codepen.io/savehansson/pen/rsIEp

      • chmod

        • #shell
        08-16-2020
        • chmod +rwx <filename> to add permissions.
        • chmod -rwx <directoryname> to remove permissions.
        • chmod +x <filename> to allow executable permissions.
        • chmod -wx <filename> to take out write and executable permissions.
      • Array._proto__.length

        • #ecmascript
        08-05-2020

        js array๋Š” object์ด๊ณ  length ํ”„๋กœํผํ‹ฐ๋ฅผ ๊ฐ–๊ณ  ์žˆ๋‹ค. ๊ทธ๋ž˜์„œ ์•„๋ž˜๊ฐ€ ๊ฐ€๋Šฅ.

        const {length, [0]: first, [length - 1]: last} = [1, 2, 3];
        
        console.log(first, last);  // 1 3

        ์ฃผ์˜: length๋ฅผ ์„ ์–ธํ•ด๋‘์ง€ ์•Š์œผ๋ฉด length - 1์„ ์•Œ ์ˆ˜ ์—†๊ณ  last๊ฐ€ undefined ๋˜์–ด๋ฒ„๋ฆผ.

      • asdf nodejs

        • #asdf
        • #version_manager
        07-30-2020
        1. asdf๋ฅผ ์„ค์น˜ํ•œ๋‹ค.
          brew install asdf
        2. gpg๋ฅผ ์„ค์น˜ํ•œ๋‹ค.
          brew install gpg
        3. asdf nodejs plugin์„ ์„ค์น˜ํ•œ๋‹ค.
          asdf plugin-add nodejs https://github.com/asdf-vm/asdf-nodejs.git
        4. nodejs release team์˜ gpg key๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.
          bash -c '${ASDF_DATA_DIR:=$HOME/.asdf}/plugins/nodejs/bin/import-release-team-keyring'
        5. nvm๋“ฑ ์‚ฌ์šฉ์ค‘์ด๋˜ vm์ด ์žˆ๋‹ค๋ฉด ํ˜ธํ™˜์„ฑ์„ ์œ„ํ•ด ~/.asdfrc์— ์•„๋ž˜๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.
          legacy_version_file = yes
        6. ๋ซ๋‹ค.

        how to uninstall node

        https://reactgo.com/uninstall-node-npm-from-macos/

      • how to stash single file

        • #git
        07-21-2020
        git stash -- <filename>
        git stash push -m "<message>" <filename.ext>
      • Delegation Pattern

        • #oop
        07-06-2020

        https://en.wikipedia.org/wiki/Delegation_pattern

        class Rectangle(val width: Int, val height: Int) {
            fun area() = width * height
        }
        
        class Window(val bounds: Rectangle) {
            // Delegation
            fun  area() = bounds.area()
        }

        Links

      • Xcode ํ„ฐ๋ฏธ๋„์—์„œ ์‹คํ–‰ํ•˜๊ธฐ

        • #xcode
        06-30-2020
        $ xed .
      • Vertical rulers in vscode

        • #devtools
        • #vscode
        06-28-2020

        rulers?

        settings.json์— ์•„๋ž˜ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด,

        "editor.rulers": [
          80,
          100,
          120
        ],

        Screen Shot 2020-06-22 at 9 24 27 AM

        ์œ„์™€ ๊ฐ™์ด 80, 100, 120์ž ์œ„์น˜์— ์„ธ๋กœ์ค„์ด ์ƒ๊ธด๋‹ค.
        ์•ˆ ๋ณด์ด๋˜ ๊ฒŒ ๋ณด์ด๋Š” ๊ฑด ์—ญ์‹œ ์ข‹์€ ์ผ์ด๋‹ค.

        customization

        ์„ธ๋กœ์ค„์˜ ์ปฌ๋Ÿฌ๋ฅผ ์•„๋ž˜์™€ ๊ฐ™์ด ์ปค์Šคํ…€ ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

        "workbench.colorCustomizations": {
            "editorRuler.foreground": "#ff4081"
        }

        References

      • How to find out what font is actually rendered

        • #css
        • #devtools
        06-27-2020

        See 'Rendered Fonts' section in devtools.๐Ÿ˜›

        Screen Shot 2020-06-18 at 11 59 50 AM

      ยฉ2021 Sehyun Chung