Pixi.js: ๋„์›€์„ ๊ตฌํ•จ: TypeScript ๋ณ€ํ™˜ ์—…๋ฐ์ดํŠธ

์— ๋งŒ๋“  2020๋…„ 02์›” 01์ผ  ยท  24์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: pixijs/pixi.js

์•ˆ๋…•ํ•˜์„ธ์š”, PixiJS ์ปค๋ฎค๋‹ˆํ‹ฐ,

ํ•ต์‹ฌ ๋ฐ ๋ชจ๋“  ์ข…์†์„ฑ์„ ๋ณ€ํ™˜ํ•˜์—ฌ PixiJS๋ฅผ TypeScript๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์ฃผ์š” ์ด์ •ํ‘œ์— ๋„๋‹ฌํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด์ œ ์ด ๊ณ ๋น„๋ฅผ ๋„˜์—ˆ์œผ๋ฏ€๋กœ ์ด ์ž‘์€ ํ•ต์‹ฌ ํŒจํ‚ค์ง€ ์„ธํŠธ์— ์˜์กดํ•˜๋Š” ๋‚˜๋จธ์ง€ ํŒจํ‚ค์ง€์—์„œ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ์ด ํŒจํ‚ค์ง€์˜ ๋‚˜๋จธ์ง€ ๋ถ€๋ถ„์„ ๋ณ€ํ™˜ํ•˜๊ธฐ ์œ„ํ•ด ๊ฐœ๋ฐœ์ž์˜ ์†์„ ํ™•์‹คํžˆ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํŒจํ‚ค์ง€ ๋ณ€ํ™˜์— ๊ด€์‹ฌ์ด ์žˆ์œผ์‹œ๋ฉด ์–ด๋–ค ํŒจํ‚ค์ง€์ธ์ง€ ์•Œ๋ ค์ฃผ์‹ญ์‹œ์˜ค. ๊ธฐ์กด์— ์™„๋ฃŒ๋œ PR์—์„œ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ํŒจํ‚ค์ง€ ๋ณ€ํ™˜์— ๋Œ€ํ•œ ๋ช‡ ๊ฐ€์ง€ ์ง€์นจ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

Gotchyas ๋ณ€ํ™˜

  • ๋ชจ๋“  ๊ฒƒ์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ JSDocs๋ฅผ ์œ ์ง€ ๊ด€๋ฆฌํ•œ ๋‹ค์Œ Typedoc๋กœ ๋ณ€ํ™˜ํ•˜๊ณ  ๋‚˜์ค‘์— ์œ ํ˜•์„ ๋‚ด๋ณด๋‚ด๋ ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. JSDocs๋ฅผ ์œ ์ง€ ๊ด€๋ฆฌํ•˜๊ณ  npm run docs ๋ฅผ ํ†ตํ•ด ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๋นŒ๋“œ๋˜๊ณ  ํ‘œ์‹œ๋˜๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.
  • git mv ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ JS ํŒŒ์ผ์˜ ์ด๋ฆ„์„ TS๋กœ ๋ฐ”๊พธ์‹ญ์‹œ์˜ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด Git ๊ธฐ๋ก์ด ์†์‹ค๋ฉ๋‹ˆ๋‹ค. ์ผ๋ถ€ Git GUI๋Š” ์ด๋Ÿฌํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์„ ํƒํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋‚ด๋ถ€ ์ „์šฉ ๋ฉ”์†Œ๋“œ๋‚˜ ๋ฉค๋ฒ„์— public ์•ก์„ธ์Šค ์ˆ˜์ •์ž๋ฅผ ์ถ”๊ฐ€ํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค. ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ ์•ก์„ธ์Šค๋ฅผ ์ •์˜๋˜์ง€ ์•Š์€ ์ƒํƒœ๋กœ ๋‘์‹ญ์‹œ์˜ค.

ํŒจํ‚ค์ง€

ํŒจํ‚ค์ง€๋ฅผ ์ฒญ๊ตฌํ•˜๋ ค๋ฉด ํ•ด๋‹น ํŒจํ‚ค์ง€์— ๋Œ€ํ•œ PR ์ดˆ์•ˆ์„ ์ž‘์„ฑํ•˜์‹ญ์‹œ์˜ค.

  • [x] @pixi/accessibility #6379
  • [x] @pixi/app #6376
  • [x] @pixi/constants #6173
  • [x] @pixi/core #6340, #6373
  • [x] @pixi/display #6261, #6339, #6349, #6371
  • [x] @pixi/extract #6381
  • [x] @pixi/graphics #6352
  • [x] @pixi/interaction #6656
  • [x] @pixi/loaders #6385
  • [x] @pixi/math #6141
  • [x] @pixi/mesh-extras #6396
  • [x] @pixi/mesh #6382
  • [x] @pixi/mixin-cache-as-bitmap #6630
  • [x] @pixi/mixin-get-child-by-name #6621
  • [x] @pixi/mixin-get-global-position #6637
  • [x] @pixi/particles #6449
  • [x] @pixi/polyfill #6654, #6669
  • [x] @pixi/prepare #6481
  • [x] @pixi/runner #6164
  • [x] @pixi/settings #6315
  • [x] @pixi/sprite-animated #6397
  • [x] @pixi/sprite-tiling #6398
  • [x] @pixi/sprite #6375
  • [x] @pixi/spritesheet #6389
  • [x] @pixi/text-bitmap #6479
  • [x] @pixi/text #6390
  • [x] @pixi/ticker #6186
  • [x] @pixi/unsafe-eval #6655
  • [x] @pixi/utils #6262
  • [x] @pixi/canvas-display #6659
  • [x] @pixi/canvas-extract #6503
  • [x] @pixi/canvas-graphics #6663
  • [x] @pixi/canvas-mesh #6664
  • [x] @pixi/canvas-particles #6622
  • [x] @pixi/canvas-prepare #6657
  • [x] @pixi/canvas-renderer #6499
  • [x] @pixi/canvas-sprite-tiling #6665
  • [x] @pixi/canvas-sprite #6658
  • [x] @pixi/canvas-text #6666
  • [x] @pixi/filter-alpha #6383
  • [x] @pixi/filter-blur #6383
  • [x] @pixi/filter-color-matrix #6383
  • [x] @pixi/filter-displacement #6383
  • [x] @pixi/filter-fxaa #6383
  • [x] @pixi/filter-noise #6383

๋ฌถ์Œ

  • [ ] pixi.js-legacy #6673 ์ง„ํ–‰ ์ค‘ @bigtimebuddy
  • [ ] pixi.js #6673 ์ง„ํ–‰ ์ค‘ @bigtimebuddy

๊ฐ€์žฅ ์œ ์šฉํ•œ ๋Œ“๊ธ€

๋‚˜๋Š” ํƒ€์ดํ•‘ ์ œํ•œ์„ ์ˆ˜์šฉํ•˜๊ธฐ ์œ„ํ•ด API๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์„ ์‹ซ์–ดํ•˜์ง€๋งŒ ๋‚˜์—๊ฒŒ ์˜ณ์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ์ธ์ ์œผ๋กœ ๋‚˜๋Š” ์ฐจ๋ผ๋ฆฌ ์•„๋ฌด๊ฑฐ๋‚˜ ์‚ฌ์šฉํ•˜๊ณ  ์ƒˆ๋กœ์šด ๋ฐฉ๋ฒ•์„ ๋งŒ๋“ค๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํฐ API ํ‘œ๋ฉด์„ ๊ฐ–๋Š” ๊ฒƒ์€ ์ด๋ฏธ ๋ถ€๋‹ด์ž…๋‹ˆ๋‹ค.

๋ชจ๋“  24 ๋Œ“๊ธ€

์ถ”๊ฐ€ ํŒ:

  • ๊ธฐ์กด ๊ฐ€์ ธ์˜ค๊ธฐ์™€ ๋ณ„๋„๋กœ ๋ชจ๋“  ์ถ”๊ฐ€ import (์‹ค์ œ๋กœ๋Š” ๊ฐ€์ ธ์˜ค๊ธฐ ์œ ํ˜•)๋ฅผ ๋„ฃ์œผ์‹ญ์‹œ์˜ค. ์ƒˆ๋กœ์šด TS ๋ฒ„์ „์ด ์ถœ์‹œ๋˜๋ฉด import type ๋ฅผ ์ถ”๊ฐ€ํ•  ์˜ˆ์ •์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ linter๋Š” ๋™์ผํ•œ ๋ชจ๋“ˆ์—์„œ import ์˜ ๋‘ ์ค„์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๋ง‰์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๊ฒฝ์šฐ์—๋Š” ๊ทธ๊ฒƒ๋“ค์„ ํ˜ผํ•ฉํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

  • Array<X> ๋ฐ X[] ํ‘œ๊ธฐ๋ฒ•์„ ๋ชจ๋‘ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ €๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์ž์ฃผ ํ‘ธ์‹œ-ํŒ๋˜๋Š” ๊ตฌ์กฐ(์ผ๋ช… ๋ชฉ๋ก)์— Array<X> ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. X[] ๊ณ ์ •๋œ ์ž‘์€ ๊ธธ์ด๋ฅผ ๊ฐ€์ง€๊ฑฐ๋‚˜ ํฌ๊ธฐ๊ฐ€ ๊ฐ™์€ ์œ„์น˜์—์„œ ๊ฒฐ์ •๋˜๋ฉด ๊ตฌ์„ฑ๋ฉ๋‹ˆ๋‹ค(์ผ๋ฐ˜ ๋ฐฐ์—ด).

  • readonly ํ•„๋“œ๊ฐ€ destroy() ์—์„œ๋งŒ ๋ณ€๊ฒฝ๋œ ๊ฒฝ์šฐ - any ๋ณ€ํ™˜์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๊ณณ์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ readonly ์ œ๊ฑฐํ•˜์‹ญ์‹œ์˜ค. ๋‚˜์ค‘์— private field + readonly property ๋กœ ๋งŒ๋“ค์ง€ ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ˆ„๊ตฐ๊ฐ€๊ฐ€ ๋‚˜๋ฅผ ์ด๊ธฐ์ง€ ์•Š๋Š” ํ•œ ์ด๋ฒˆ ์ฃผ๋ง์— @pixi-text ๋ฅผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฐธ๊ณ : @pixi-tiling์—๋Š” PIXI.TilingSprite.from ๊ฐ€ ํฌํ•จ๋˜๋ฉฐ TS์—์„œ ํ•  ์ˆ˜ ์—†๋Š” ๋ฐค์ž…๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋‹จ์ง€ ๊ทธ๊ฒƒ์„ ๋น„์ถ”์ฒœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํž˜๋‚ด์„ธ์š”, @qtiki. ์ด์ƒํ•œ ์ ์„ ๋ฐœ๊ฒฌํ•  ๊ฒฝ์šฐ๋ฅผ ๋Œ€๋น„ํ•˜์—ฌ ์ฃผ๋ง์— ์˜จ๋ผ์ธ์— ์ ‘์†ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

์ข‹์•„, @qtiki , ๋‹น์‹ ์˜ ์„ ํƒ์€ ์ดˆ์•ˆ PR์„ ๋ณด๋‚ธ ํ›„ ์˜ˆ์•ฝ๋ฉ๋‹ˆ๋‹ค.
๊ฐ์‚ฌ ํ•ด์š”!

๋™์˜. Draft PR์€ ๋ณ€ํ™˜ํ•  ํŒจํ‚ค์ง€๋ฅผ ์š”์ฒญํ•˜๋Š” ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์ž…๋‹ˆ๋‹ค. ๋„์›€์„ ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค

์ข‹์•„, @qtiki , ๋‹น์‹ ์˜ ์„ ํƒ์€ ์ดˆ์•ˆ PR์„ ๋ณด๋‚ธ ํ›„ ์˜ˆ์•ฝ๋ฉ๋‹ˆ๋‹ค.
๊ฐ์‚ฌ ํ•ด์š”!

PR #6390 ์ดˆ์•ˆ์„ ์—ด์—ˆ์Šต๋‹ˆ๋‹ค. PR์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ๋„๋ก ์ผ๋ถ€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ ์šฉํ•˜๊ธฐ ์œ„ํ•ด .js ํŒŒ์ผ์˜ ์ด๋ฆ„์„ .ts๋กœ ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฒˆ ์ฃผ๋ง์— ์‹ค์ œ ๋ณ€ํ™˜์„ ์‹œ๋„ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

Text ํŒจํ‚ค์ง€๋ฅผ TypeScript๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๋™์•ˆ ๊ฒช์—ˆ๋˜ ๋ช‡ ๊ฐ€์ง€ ์ผ๋ฐ˜์ ์ธ ์‚ฌํ•ญ:

๊ทธ๋ž˜์„œ TypeScript ์†์„ฑ์— ๊ทผ๋ณธ์ ์ธ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. TypeScript๋Š” ์†์„ฑ getter ๋ฐ setter์— ๋Œ€ํ•ด ๋‹ค๋ฅธ ์œ ํ˜•์„ ์ง€์›ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค: https://github.com/microsoft/TypeScript/issues/2521

Text ๋ฐ TextStyle ํด๋ž˜์Šค์—๋Š” ์ด๊ฒƒ์ด ํฐ ์ด์ ์ด ๋  ๋ถ€๋ถ„์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด TextStyle์˜ fillStyle ๋ฐ stroke ๋Š” ์ˆซ์ž๋ฅผ ๋ฐ›์•„๋“ค์ธ ๋‹ค์Œ ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜๋˜๋ฏ€๋กœ getter๋Š” ์ˆซ์ž๊ฐ€ ์žˆ๋Š” ๊ณต์šฉ์ฒด ์œ ํ˜•์„ ๋ฐ˜ํ™˜ํ•˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด์ œ ์ˆซ์ž๊ฐ€ ์žˆ๋Š” ๊ณต์šฉ์ฒด ์œ ํ˜•์„ ๋ฐ˜ํ™˜ํ•˜๋ฏ€๋กœ CanvasRenderingContext2D fillStyle ์— ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ณ€ํ™˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ Text ํด๋ž˜์Šค ์ž์ฒด๋Š” new TextStyle ๋˜๋Š” TextStyle์˜ ์ธ์Šคํ„ด์Šค์— ์ง์ ‘ ์ „๋‹ฌ๋˜๋Š” ํ…์ŠคํŠธ ์Šคํƒ€์ผ์˜ ๊ฐœ์ฒด๋ฅผ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ ์—ฌ๊ธฐ์—์„œ getter๋Š” ํ•ญ์ƒ TextStyle ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€๋งŒ setter์™€ ๋™์ผํ•œ ๊ณต์šฉ์ฒด ์œ ํ˜•์œผ๋กœ ์ž…๋ ฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์‚ฌ์šฉ์ž ์˜์—ญ์—์„œ ์ผ๋ถ€ ๋ถˆํ•„์š”ํ•œ ์œ ํ˜• ๊ฒ€์‚ฌ(๋˜๋Š” ์บ์ŠคํŠธ)๊ฐ€ TextStyle์˜ ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์žฅ๊ธฐ์ ์œผ๋กœ ์ด ๋ฌธ์ œ์— ๋Œ€ํ•œ ์ตœ์„ ์˜ ํ•ด๊ฒฐ์ฑ…์ด ๋ฌด์—‡์ธ์ง€๋Š” ์ž˜ ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ ์ง€๊ธˆ์œผ๋กœ์„œ๋Š” ๊ทธ๋ ‡๊ฒŒ ํ•ด์•ผ ํ•  ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ์œ ํ˜•์˜ ๋กœ์ปฌ ๋ณ€์ˆ˜๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ์ƒ๋‹นํžˆ ๋งŽ๋‹ค๋Š” ์‚ฌ์‹ค์„ ์•Œ๊ฒŒ ๋˜์—ˆ๊ณ  TypeScript์—์„œ๋Š” ์ž˜ ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด ์ฝ”๋“œ๋ฅผ ๋„ˆ๋ฌด ๋งŒ์ง€๊ณ  ์‹ถ์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ์œ ๋‹ˆ์˜จ ์œ ํ˜•๊ณผ ์—ฌ๊ธฐ ์ €๊ธฐ์— ์ถ”์•…ํ•œ ์บ์ŠคํŒ…์„ ์‚ฌ์šฉํ•˜์—ฌ ์ปดํŒŒ์ผํ•˜๋„๋ก ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๊ฒƒ๋“ค์€ ์‹œ๊ฐ„์ด ์ง€๋‚˜๋ฉด์„œ ๋ณด์ด์Šค์นด์šฐํŠธ ์›์น™ ์œผ๋กœ ๊ฐœ์„ ๋  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

@qtiki
PR ๋Œ€์‹  ์ด ์ฃผ์ œ์— ๋ฌธ์ œ๋ฅผ ์“ฐ๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

@qtiki
PR ๋Œ€์‹  ์ด ์ฃผ์ œ์— ๋ฌธ์ œ๋ฅผ ์“ฐ๋Š” ์ด์œ ๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?

๋‚˜๋Š” ์ด๊ฒƒ์ด ์‚ฌ๋žŒ๋“ค์ด TypeScript ๋ณ€ํ™˜๊ณผ ํ•จ๊ป˜ ํ…์ŠคํŠธ ํŒจํ‚ค์ง€ ํŠน์ • ๋ฌธ์ œ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ๋‹ค๋ฅธ ๊ณณ์—์„œ ๊ฒช์„ ์ผ๋ฐ˜์ ์ธ ๋ฌธ์ œ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์†์„ฑ ๋ฌธ์ œ๋Š” ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ž…๋ ฅํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ๋ฏธ๋ž˜์— ๋Œ€ํ•œ ๊ทผ๋ณธ์ ์ธ ์„ค๊ณ„ ๋ฌธ์ œ์ž…๋‹ˆ๋‹ค.

TypeScript setter ๋ฐ getter๊ฐ€ ๋ฐœ์ƒํ•œ ์ดํ›„๋กœ ๋‹ค๋ฅธ ์œ ํ˜•์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ๋ฌธ์ œ๋ฅผ ์—ฐ๊ตฌํ•ด ์™”์Šต๋‹ˆ๋‹ค. ๋ฌธ์ œ๋Š” ๋งค์šฐ ๋ณต์žกํ•œ ๋ฌธ์ œ์ด๋ฉฐ "์ˆ˜์ •"๋˜์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋Ÿฌํ•œ ์œ ํ˜•์˜ ์†์„ฑ์„ TypeScript๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ์ผ๋ฐ˜์ ์ธ ์ง€์นจ์— ๋Œ€ํ•œ ์ œ ์ œ์•ˆ์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์€ ์šฐ๋ฆฌ๊ฐ€ ์›ํ•˜๋Š” ๊ฒƒ์˜ ๋‹จ์ˆœํ™”๋œ ์˜ˆ์ž…๋‹ˆ๋‹ค. string | number ๋ฅผ ํ—ˆ์šฉํ•˜์ง€๋งŒ ๋‚ด๋ถ€์ ์œผ๋กœ string ๋กœ ์ €์žฅ๋˜๊ณ  ๋ฐ˜ํ™˜๋˜๋Š” ์†์„ฑ์ž…๋‹ˆ๋‹ค. ๋‹น์—ฐํžˆ ์†์„ฑ์„ string | number ๋กœ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์ด๋Š” API ์‚ฌ์šฉ์ž๊ฐ€ ์™„์ „ํžˆ ๋ถˆํ•„์š”ํ•œ ์œ ํ˜• ๊ฒ€์‚ฌ์— ์ง๋ฉดํ•˜๊ฒŒ ๋จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

class Foo {
    constructor() {
        this._bar = '';
    }

    // error: 'get' and 'set' accessor must have the same type.(2380)
    get bar(): string {
        return this._bar;
    }

    // error: 'get' and 'set' accessor must have the same type.(2380)
    set bar(value: string | number) {
        this._bar = value.toString();
    }

    private _bar: string;
}

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

class Foo {
    constructor() {
        this._bar = '';
    }

    // Return the strictest type possible in the getter.
    get bar(): string {
        return this._bar;
    }

    // Use the same strict type for the setter as the getter.
    set bar(value: string) {
        // Call the conversion function.
        this.setBar(value);
    }

    // Implement a separate conversion function that accepts all supported types.
    public setBar(value: number | string) {
        this._bar = value.toString();
    }

    private _bar: string;
}

์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ์†์„ฑ์„ ์ฝ์„ ๋•Œ ์˜ฌ๋ฐ”๋ฅธ ์œ ํ˜•์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. number ๋ฅผ bar ์— ํ• ๋‹นํ•˜๋ ค๋Š” TypeScript ์‚ฌ์šฉ์ž๋Š” setBar ๋ณ€ํ™˜ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๊ฒƒ์€ ์†์„ฑ setter๊ฐ€ ๋ณ€ํ™˜ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ธฐ์กด JavaScript ์‚ฌ์šฉ์ž์— ๋Œ€ํ•œ ์ฃผ์š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์•„๋‹™๋‹ˆ๋‹ค. ์ด๋Š” ์œ ํ˜•์ด ์ง€์ •๋˜์ง€ ์•Š์€ ์†์„ฑ setter๊ฐ€ ์‹ค์ œ๋กœ ์ˆซ์ž๋ฅผ ํ—ˆ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ๋ถ„์€ ์–ด๋–ป๊ฒŒ ์ƒ๊ฐํ•˜์„ธ์š”? ์ด๊ฒŒ ๋ง์ด ๋˜๋‚˜์š”? ์ด ์œ ํ˜•์˜ ํŒจํ„ด์ด ์–ผ๋งˆ๋‚˜ ์ž์ฃผ ์‚ฌ์šฉ๋˜๋Š”์ง€ ์ž˜ ๋ชจ๋ฅด๊ฒ ์ง€๋งŒ ์ ์–ด๋„ ํ…์ŠคํŠธ ํŒจํ‚ค์ง€์—์„œ ๋‘ ๋ฒˆ ์ด์ƒ ๋งŒ๋‚ฌ์Šต๋‹ˆ๋‹ค.

๋‚˜๋Š” ํƒ€์ดํ•‘ ์ œํ•œ์„ ์ˆ˜์šฉํ•˜๊ธฐ ์œ„ํ•ด API๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๊ฒƒ์„ ์‹ซ์–ดํ•˜์ง€๋งŒ ๋‚˜์—๊ฒŒ ์˜ณ์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ์ธ์ ์œผ๋กœ ๋‚˜๋Š” ์ฐจ๋ผ๋ฆฌ ์•„๋ฌด๊ฑฐ๋‚˜ ์‚ฌ์šฉํ•˜๊ณ  ์ƒˆ๋กœ์šด ๋ฐฉ๋ฒ•์„ ๋งŒ๋“ค๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํฐ API ํ‘œ๋ฉด์„ ๊ฐ–๋Š” ๊ฒƒ์€ ์ด๋ฏธ ๋ถ€๋‹ด์ž…๋‹ˆ๋‹ค.

๋‚˜๋Š” set* ๋ฐฉ๋ฒ•์œผ๋กœ ํ•ดํ‚น์„ ์Šน์ธํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋ฉฐ any ์œ ํ˜•์ด set* ๋ฐฉ๋ฒ•๋ณด๋‹ค ๋” ์นœ์ˆ™ํ•˜๋‹ค๋Š” @bigtimebuddy ์˜ ์˜๊ฒฌ์— ๋™์˜ํ•ฉ๋‹ˆ๋‹ค.

ํ˜„์žฌ์˜ ๊ฒฝ์šฐ getter์— ๋Œ€ํ•ด (string | number) ์œ ํ˜•์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒƒ์ด ์ƒ๋‹นํžˆ ํ—ˆ์šฉ๋ฉ๋‹ˆ๋‹ค.

์‹ค์ œ๋กœ setBar ๋Š” set ์˜ ์ƒ์† ๋ฌธ์ œ ๋•Œ๋ฌธ์— ์ข‹์€ ์ƒ๊ฐ์ด์ง€๋งŒ _$setBar() ์™€ ๊ฐ™์ด prefx์— ๋” ๋งŽ์€ ๊ธฐํ˜ธ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. :) ํ•˜์ง€๋งŒ ์ด ๊ฒฝ์šฐ์—๋Š” ๊ทธ๋ ‡์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

@qtiki ๋ฌธ์ œ๋ฅผ ๊ฐ•์กฐํ•ด ์ฃผ์…”์„œ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ œ ์ž‘์—… ํ”„๋กœ์ ํŠธ๋ฅผ ์œ„ํ•ด pixijs ts fork๋ฅผ ๋งŒ๋“ค ๋•Œ ์—ฌ๋Ÿฌ ๋ฒˆ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ, Text ๋Š” ๊ณ ํ†ต์ž…๋‹ˆ๋‹ค. ์˜ˆ, ์šฐ๋ฆฌ๋Š” ๊ทธ๊ฒƒ์— ๋Œ€ํ•ด ๋” ์ƒ๊ฐํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

setBar ๊ฐ€ ๊ฐ€์žฅ ์ข‹์€ ์†”๋ฃจ์…˜์ด ์•„๋‹ˆ๋ผ๋Š” ๋ฐ ๋™์˜ํ•ฉ๋‹ˆ๋‹ค. ์†”์งํžˆ ๋งํ•ด์„œ TypeScript๊ฐ€ type-coercion๊ณผ ํ•จ๊ป˜ ์ด๋Ÿฌํ•œ ์ข…๋ฅ˜์˜ setter๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์‚ฌ์‹ค์— ์ƒ๋‹นํžˆ ๋†€๋ž์Šต๋‹ˆ๋‹ค. TypeScript์˜ ํ๋ฆ„ ์ œ์–ด์™€ ๊ด€๋ จํ•˜์—ฌ ์ด๋Ÿฌํ•œ ์†์„ฑ์— ๋Œ€ํ•ด ๋” ๋Š์Šจํ•œ ํƒ€์ดํ•‘ ๋˜๋Š” any ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์˜๋ฏธํ•˜๋Š” ๋ฐ”๋Š” ๊ฒฝ๊ณ ์ž…๋‹ˆ๋‹ค.

class Foo {
    constructor() {
        this._bar = '';
    }

    get bar(): string | number {
        return this._bar;
    }

    set bar(value: string | number) {
        this._bar = value.toString();
    }

    private _bar: string;
}

const foo = new Foo();

// TypeScript's flow control will assume from now on that `bar` is a `number`
foo.bar = 42;

function add(a: number, b: number) {
    return a + b;
}

// Call to `add` shouldn't be allowed since the value in `bar` is actually a string
// This will print `4242` instead of `84`
console.log(add(foo.bar, 42));

์žฅ๊ธฐ์ ์œผ๋กœ ๊ฐ€์žฅ ๊นจ๋—ํ•œ ์˜ต์…˜์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

class Bar {
    constructor() {
        this._bar = '';
    }

    get(): string {
        return this._bar;
    }

    set(value: string | number) {
        this._bar = value.toString();
    }

    private _bar: string;
}

class Foo {
    constructor() {
        this.bar = new Bar();
    }

    public bar: Bar;
}

const foo = new Foo();
foo.bar.set(42);
console.log(foo.bar.get());

์ด๋Ÿฌํ•œ ์œ ํ˜•์˜ set ๋Š” PIXI.Point ๊ฐ€ ๊ตฌํ˜„๋˜๋Š” ๋ฐฉ์‹์ด๋ฏ€๋กœ ์ „๋ก€๊ฐ€ ์—†๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ชจ๋“  ์‚ฌ์šฉ์ž ๋Œ€๋ฉด API๋Š” ๋ชจ๋“  ๊ณณ์—์„œ ์ˆ˜๋™์œผ๋กœ get ๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š๊ณ ๋„ Bar ์ธ์Šคํ„ด์Šค๋ฅผ "์žˆ๋Š” ๊ทธ๋Œ€๋กœ" ๋ฐ›์•„๋“ค์ผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋‹น์—ฐํžˆ ์ด๊ฒƒ์€ ํš๊ธฐ์ ์ธ ๋ณ€ํ™”๊ฐ€ ๋  ๊ฒƒ์ด๋ฏ€๋กœ ๊ฐ€๊นŒ์šด ์žฅ๋ž˜์— ๋Œ€ํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ๊ทธ๋ƒฅ 2์„ผํŠธ๋ฅผ ๋„ฃ๊ณ  ์‹ถ์—ˆ์Šต๋‹ˆ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ €๋Š” ์ด์ „ ์ œ์•ˆ์ด ๋” ์ด์ƒ "์‹ค์ œ" ์†์„ฑ์ด ์•„๋‹ˆ๋ฏ€ Object.assign ์™€ ๊ฐ™์€ ๊ฒƒ๋“ค์ด ๋” ์ด์ƒ setter์—์„œ ์ž‘๋™ํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ๊นจ๋‹ฌ์•˜์Šต๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๊ฒฐ๊ตญ ์ตœ๊ณ ์˜ ์•„์ด๋””์–ด๊ฐ€ ์•„๋‹ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์•ˆ๋…•ํ•˜์„ธ์š”, ์ €๋Š” ์˜ค๋žซ๋™์•ˆ PixiJS ์‚ฌ์šฉ์ž์ด์ž Typescript ์‚ฌ์šฉ์ž์ž…๋‹ˆ๋‹ค. ๋‚˜๋Š” ์ด๊ฒƒ์— ๊ธฐ์—ฌํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค - ์ด ์‹œ์ ์—์„œ ๋Œ€๋ถ€๋ถ„์˜ ํŒจํ‚ค์ง€๊ฐ€ ์™„๋ฃŒ๋œ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ž…๋‹ˆ๋‹ค. ์บ”๋ฒ„์Šค๋ฅผ ์ œ์™ธํ•˜๊ณ . ๋‚ด๊ฐ€ ๋„์šธ ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด ์žˆ์Šต๋‹ˆ๊นŒ?

@lloydevans ๋„ค!!! ์ค€๋น„ ๋˜๋Š” ํ…์ŠคํŠธ ๋น„ํŠธ๋งต์„ ํ•˜๊ณ  ์‹ถ์œผ์‹ญ๋‹ˆ๊นŒ? ๋‘˜ ๋‹ค ๋งค์šฐ ๋ณต์žกํ•œ ํŒจํ‚ค์ง€๊ฐ€ ์•„๋‹ˆ๊ธฐ๋ฅผ ๋ฐ”๋ž๋‹ˆ๋‹ค.

@bigtimebuddy ํ…์ŠคํŠธ ๋น„ํŠธ๋งต ์ž‘์—…์„ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ข‹์€ ์†Œ๋ฆฌ! ์‹œ์ž‘ํ•˜๋ฉด ์—ฌ๊ธฐ์—์„œ ์ถ”์ ํ•  ์ˆ˜ ์žˆ๋„๋ก PR ์ดˆ์•ˆ์„ ์ž‘์„ฑํ•˜์‹ญ์‹œ์˜ค.

์•Œ์•˜์–ด ํ• ๊ฒŒ. ๊ธฐ์กด ์ „ํ™˜ ๋ฐ PR ์ค‘ ์ผ๋ถ€๋ฅผ ์ง€๊ธˆ ์‚ดํŽด๋ณด๊ณ  ๊ทธ์— ๋”ฐ๋ฅผ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

npm์˜ ๊ฐœ๋ณ„ ํŒจํ‚ค์ง€์—๋Š” ์—ฌ์ „ํžˆ ์œ ํ˜•์ด ์—†๋Š” ๊ฒƒ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋œ ํ›„์— ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋Š” ๋ฌธ์ œ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์œ ํ˜• ์•ˆ์ „์„ฑ์„ ํฌ์ƒํ•˜์ง€ ์•Š๊ณ  ๋นŒ๋“œ ํฌ๊ธฐ๋ฅผ ์ค„์ด๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๋ฉด ์ข‹์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

๋ชจ๋‘ ํ™ˆ ์ŠคํŠธ๋ ˆ์น˜! ํŒจํ‚ค์ง€๊ฐ€ ๋ช‡ ๊ฐœ ๋‚จ์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค!

@Zyie , @ivanpopelyshev , @SerG-Y, @eXponenta ๋ฐ ์ด ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ค€ ๋‹ค๋ฅธ ๋ชจ๋“  ๊ธฐ์—ฌ์ž์—๊ฒŒ ํฐ ๊ฐ์‚ฌ๋ฅผ ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

์ด ํŽ˜์ด์ง€๊ฐ€ ๋„์›€์ด ๋˜์—ˆ๋‚˜์š”?
0 / 5 - 0 ๋“ฑ๊ธ‰