Language-tools: ๊ธฐ๋ณธ DOM ์š”์†Œ์— ๋Œ€ํ•œ ์‚ฌ์šฉ์ž ์ •์˜ ์ด๋ฒคํŠธ ์ง€์›

์— ๋งŒ๋“  2020๋…„ 08์›” 05์ผ  ยท  4์ฝ”๋ฉ˜ํŠธ  ยท  ์ถœ์ฒ˜: sveltejs/language-tools

๊ธฐ๋Šฅ ์š”์ฒญ์ด ๋ฌธ์ œ์™€ ๊ด€๋ จ๋˜์–ด ์žˆ์Šต๋‹ˆ๊นŒ?
๊ธฐ๋ณธ DOM ์š”์†Œ์— ์‚ฌ์šฉ์ž ์ •์˜ ์ด๋ฒคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๋ ค๊ณ  ํ•  ๋•Œ ๋‹ค์Œ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

Type '{ onswipestart: (event: CustomEvent<any>) => void; onswipemove: (event: CustomEvent<any>) => void; onswipeend: (event: CustomEvent<any>) => void; style: string; class: string; }' is not assignable to type 'HTMLProps<HTMLDivElement>'.
  Property 'onswipestart' does not exist on type 'HTMLProps<HTMLDivElement>'.ts(2322)

์‚ฌ์šฉ์ž ์ •์˜ ์ด๋ฒคํŠธ๋Š” Sveltes actions/use ์ง€์‹œ๋ฌธ https://svelte.dev/examples#actions๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ div ์š”์†Œ์— ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.

์›ํ•˜๋Š” ์†”๋ฃจ์…˜ ์„ค๋ช…
๋„ค์ดํ‹ฐ๋ธŒ DOM ์š”์†Œ์— ๋Œ€ํ•œ Svelte ์ž‘์—…์„ ์‚ฌ์šฉํ•˜์—ฌ ์ „๋‹ฌ๋œ ์‚ฌ์šฉ์ž ์ •์˜ ์ด๋ฒคํŠธ์— ๋Œ€ํ•œ ์œ ํ˜• ๊ฒ€์‚ฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ณ ๋ คํ•œ ๋Œ€์•ˆ์„ ๊ธฐ์ˆ ํ•˜์‹ญ์‹œ์˜ค
div๋ฅผ ๊ฐœ๋ณ„ Svelte ๊ตฌ์„ฑ ์š”์†Œ๋กœ ๋ณ€ํ™˜ํ•˜๋ ค๊ณ  ์‹œ๋„ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๊ธฐ๋ณธ DOM ์š”์†Œ์—์„œ๋„ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์ด ๋ฐ”๋žŒ์งํ•ฉ๋‹ˆ๋‹ค.

์ถ”๊ฐ€ ์ปจํ…์ŠคํŠธ

The error message

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

<div
  class="bottomSheet"
  class:draggable
  bind:this={bottomSheet}
  use:swipeable
  on:swipestart={handleSwipeStart}
  on:swipemove={handleSwipeMove}
  on:swipeend={handleSwipeEnd}
  style="height:{height};bottom:{bottom};transform:translateY({$coords.ty}px);"
>

Svelte ๊ตฌ์„ฑ ์š”์†Œ์˜ ์‚ฌ์šฉ์ž ์ง€์ • ์ด๋ฒคํŠธ์— ๋Œ€ํ•œ ๊ด€๋ จ pull ์š”์ฒญ: https://github.com/sveltejs/language-tools/pull/303

enhancement

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

์•ก์…˜์ด ์žˆ๋Š” ์š”์†Œ์—๋งŒ ์ ์šฉ๋˜๋„๋ก ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ „ ์„ธ๊ณ„์ ์œผ๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

declare namespace svelte.JSX {
    interface HTMLAttributes<T> {
        onswipemove?: (event: CustomEvent<number> & { target: EventTarget & T }) => any;
    }
}

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

์•ก์…˜์ด ์žˆ๋Š” ์š”์†Œ์—๋งŒ ์ ์šฉ๋˜๋„๋ก ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์ „ ์„ธ๊ณ„์ ์œผ๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

declare namespace svelte.JSX {
    interface HTMLAttributes<T> {
        onswipemove?: (event: CustomEvent<number> & { target: EventTarget & T }) => any;
    }
}

" CustomEvent<any> ๋กœ ํด๋ฐฑ"์„ ์‚ฌ์šฉํ•˜์—ฌ ํƒ€์ดํ•‘์„ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜๋„ ์žˆ์ง€๋งŒ ๋‹ค๋ฅธ ์‚ฌ๋žŒ๋“ค์ด ์ด๋ฒคํŠธ๋ฅผ ์ž˜๋ชป ์ž…๋ ฅํ•˜๋ฉด "์กด์žฌํ•˜์ง€ ์•Š์Œ" ์˜ค๋ฅ˜๋ฅผ ๋˜์ง€๊ธฐ ์œ„ํ•ด ํƒ€์ดํ•‘์— ์˜์กดํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ €๋Š” ๊ทธ๋ ‡๊ฒŒ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์•ก์…˜์ด ์žˆ๋Š” ์š”์†Œ์—๋งŒ ์ ์šฉ๋œ๋‹ค๋ฉด ๊ทธ๋Ÿฐ ๊ฒƒ์€ ๊ดœ์ฐฎ์Šต๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ๊ฐ€ ๊ทธ๊ฒƒ์„ ์–ด๋–ป๊ฒŒ ๊ตฌํ˜„ํ• ์ง€๋Š” ์ž˜ ๋ชจ๋ฅด๊ฒ ์Šต๋‹ˆ๋‹ค.
ํ–‰๋™์—์„œ ์œ ํ˜•์„ ์ถ”๋ก ํ•˜๋Š” ๊ฒƒ์€ ๊ฑฐ์˜ ๋ถˆ๊ฐ€๋Šฅํ•œ ์ž‘์—…์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ์ž‘์—…๊ณผ ๊ฐ€๋Šฅํ•œ ์ด๋ฒคํŠธ๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ž…๋ ฅํ•˜๋„๋ก ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ๋ช…์‹œ์ ์œผ๋กœ ์ž‘์—…์„ ์ž…๋ ฅํ•˜๊ฑฐ๋‚˜ CustomEvent<any> ๋กœ ๋Œ€์ฒดํ•  ์‹œ๊ธฐ๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์„ ํƒํ•˜๊ฒŒ ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์žฅ ์ข‹์€ ์‹œ๋‚˜๋ฆฌ์˜ค์ผ ์ˆ˜ ์žˆ์ง€๋งŒ ์ง€๊ธˆ์€ @jasonlyu123 ์˜ ์†”๋ฃจ์…˜์œผ๋กœ ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ํ›Œ๋ฅญํ•œ ์ž‘์—…์— ๊ฐ์‚ฌ๋“œ๋ฆฝ๋‹ˆ๋‹ค!

๋‚˜๋Š” ์ด๊ฒƒ์„ ๋‹ค์‹œ ํ•œ ๋ฒˆ ๋ณด์•˜๊ณ  ์ง€๊ธˆ์€ ๊ฐ€์žฅ ์ข‹์€ ๋ฐฉ๋ฒ•์ด ๋ฌด์—‡์ธ์ง€์— ๋Œ€ํ•ด ์˜๊ฒฌ์ด ๋‚˜๋‰ฉ๋‹ˆ๋‹ค.

์˜ต์…˜ 1: ๋ฌด์Œ ์˜ค๋ฅ˜

use:YY ์ง€์‹œ๋ฌธ์ด ์žˆ๋Š” DOM ์š”์†Œ์˜ on:XX ์ด๋ฒคํŠธ์ธ ๊ฒฝ์šฐ ์˜ค๋ฅ˜๋ฅผ ์ˆจ๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹จ์ ์€ ์ด๋ฒคํŠธ๊ฐ€ ์•”์‹œ์ ์œผ๋กœ ๋ชจ๋“  ์œ ํ˜•์ด๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. Svelte๋Š” ๋ณธ์งˆ์ ์œผ๋กœ ๋งค์šฐ ๋™์ ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ˆ„๊ตฐ๊ฐ€ ๋ฒ„๋ธ”๋ง CustomEvents๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“  ๊ฒฝ์šฐ๋ฅผ ํฌ์ฐฉํ•˜์ง€ ๋ชปํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ต์…˜ 2: CustomEvent<any> ๋Œ€์ฒด ์ถ”๊ฐ€

๋ณธ์งˆ์ ์œผ๋กœ ๋ชจ๋“  ๋ณธ์งˆ์ ์ธ ์š”์†Œ ์œ ํ˜•์— & {[key: string]: CustomEvent<any>} ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์œ„์— ๋‚˜์—ด๋˜์ง€ ์•Š์€ _any_ ์†์„ฑ์ด CustomEvent<any> ๋กœ ๋Œ€์ฒด๋จ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ์˜ต์…˜ 1์˜ "๋™์  ํŠน์„ฑ" ๋ฌธ์ œ์™€ "์•”์‹œ์  ์ž„์˜" ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ๋ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ˆ„๊ตฐ๊ฐ€๊ฐ€ myownAttribute ์™€ ๊ฐ™์€ ์‚ฌ์šฉ์ž ์ •์˜ ์†์„ฑ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ์—๋„ ์ž˜๋ชป๋ฉ๋‹ˆ๋‹ค.

์˜ต์…˜ 3: any ๋Œ€์ฒด ์ถ”๊ฐ€

์˜ต์…˜ 2์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ & {[key: string]: any} ํด๋ฐฑ๋งŒ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์ ํ•ฉํ•˜์ง€ ์•Š์€ ๊ฒƒ์€ ๋ฌด์—‡์œผ๋กœ๋“  ๋˜๋Œ์•„๊ฐ„๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋” ์ด์ƒ ์˜คํƒ€๋ฅผ ์žก์ง€ ์•Š๋Š” ๋Œ€๊ฐ€๋กœ DOM์˜ ๋™์  ํŠน์„ฑ์— ๊ฐ€์žฅ ์ž˜ ๋งž์Šต๋‹ˆ๋‹ค.

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