ããã«ã€ããŠã¯ãã§ã«ããã€ãã®åé¡ããããŸããïŒïŒ424ãïŒ304ãïŒ273ãïŒ263ïŒãç§ãã¡ãåãããšãã§ããã¢ãããŒãã«ã€ããŠè°è«ããããã«ãçµ±åããããã®ãäœãããã£ãã®ã§ãã
é¢é£PRïŒïŒ437
ãã®åé¡ã¯d.ts
ãã¡ã€ã«ã®å
¥åã«é¢ãããã®ã§ã¯ãªãããšã«æ³šæããŠãã ãããããã¯ãåŸã§å¥ã®åé¡ãšããŠçºçããŸãã
æ©èœãªã¯ãšã¹ãã¯åé¡ã«é¢é£ããŠããŸããïŒ
çŸæç¹ã§ã¯ãç¹å®ã®ç¶æ³äžã§ã³ã³ããŒãã³ãã®å
¥å/åºåãå
¥åããããšã¯ã§ããŸããã
åžæãããœãªã¥ãŒã·ã§ã³ã説æããŠãã ãã
å°éå
·/ã€ãã³ã/ã¹ããããæ瀺çã«å
¥åããæ¹æ³ã
ææ¡ïŒæ°ããäºçŽæžã¿ã€ã³ã¿ãŒãã§ãŒã¹ComponentDef
ã¯ãå®çŸ©ããããšãã³ãŒãããç©äºãæšæž¬ãã代ããã«ãã³ã³ããŒãã³ãã®ãããªãã¯APIãšããŠäœ¿çšãããŸãã
äŸïŒäžå¯èœãšæãããããšã«ã€ããŠã®ã³ã¡ã³ãä»ãïŒïŒ
<script lang="ts"
interface ComponentDef<T> { // <-- note that we can use generics as long as they are "defined" through props
props: { items: T[] }
events: { itemClick: CustomEvent<T> }
slots: { default: { item: T } }
}
// generic type T is not usable here. Is that a good solution? Should it be possible?
// Also: How do we make sure the types match the component definition?
export items: any[];
// ...
// We cannot make sure that the dispatched event and its type are correct. Is that a problem?
// Maybe enhance the type definitions in the core repo so createEventDispatcher accepts a record of eventname->type?
dispatch('itemClick', item);
</script>
<!-- ... -->
<slot item={item}> <!-- again, we cannot make sure this actually matches the type definition -->
誰ããä»ã³ã³ããŒãã³ãã䜿çšãããšãã圌ã¯å°éå ·/ã€ãã³ã/ã¹ãããããæ£ããã¿ã€ããååŸããäœããééã£ãŠãããšãã®ãšã©ãŒèšºæãè¡ããŸãïŒ
<Child
items="{['a', 'string']}"
on:itemClick="{event => event.detail === 1 /* ERROR, number not comparable to type string */}"
/>
ãããæ©èœããå°ããã¹ããããã°ã ComponentEvents
ã®ãããªä»ã®äºçŽæžã¿ã€ã³ã¿ãŒãã§ãŒã¹ã§æ¡åŒµããŠã1ã€ã ããå
¥åããããšãã§ããŸãã
ããã¯åºã䜿çšãããå¯èœæ§ã®ãã倧ããªå€æŽã§ããå¯èœæ§ãé«ããããããã«ã€ããŠã§ããã ãå€ãã®ãã£ãŒãããã¯ãåãåããããšæããŸãã ãŸããã³ã¢ããŒã ã®ã¡ã³ããŒã®äœäººãã«ãããã圌ãã«ãšã£ãŠè¯ããããªãã®ã§ãããã圌ããåæããªãäœãã玹ä»ããå Žåã¯ããããèŠãŠããããããšæããŸãã
@ jasonlyu123 @orta @Conduitry @antony @pngwn
åççãªããã§ãããå®è¡æã«ã¹ããããæ¿å ¥ã§ãããã©ããã«ã€ããŠã¯ãå®éã«ã¯Svelteã®åé¡ããããŸãã https://github.com/sveltejs/svelte/issues/2588ãšãããå®è£ ããPRhttpsïŒ//github.com/sveltejs/svelte/pull/4296 ãéè€ãããããå°ãªããšãããã€ãã®æ©äŒãããããã«æããŸãã€ã³ã¿ãŒãã§ã€ã¹ã調æŽããŸãïŒã³ã³ã»ã³ãµã¹ãããå Žåã§ããäžèšã®PRã«ã¯æªè§£æ±ºã®è³ªåãããã€ããããŸãïŒã
PRãªã³ã¯ã®ãããã§ãã³ã³ã¹ãã©ã¯ã¿ãŒã®åãå°ãå€ããªããã°ãªããªããšããç¹ã§ã®ã¿é¢ä¿ããŠããããã§ãããããã¯ãã³ãã¬ãŒãã¬ãã«ã§ã®åãã§ãã¯ãšã¯ç¡é¢ä¿ã ãšæããŸãã
é¢çœãã
ãããªããšãã§ããããª
<script lang="ts" generic="T">
type T = unknown
export let items: T[]
let item:T = items[0]
</script>
<slot b={item}></slot>
ããã«ãããã¿ã€ããã§ãã¯äžã«type T = unknown
ãåé€ããã代ããã«ãžã§ããªãã¯åŒæ°ãšããŠã³ã³ããŒãã³ãã«è¿œå ãããŸãã
//...
render<T>() {
export let items: T[]
let item:T = items[0]
}
render
é¢æ°ã«è¿œå ããããšããå§ãããŸãã
åãçµæãåŸããããšæããŸã
<script lang="ts">
interface ComponentDef<T> {
...
}
type T = unknown
export let items: T[]
let item:T = items[0]
</script>
<slot b={item}></slot>
ã€ã³ã¿ãŒãã§ã€ã¹å®çŸ©ããT
ãæœåºããŸãã
ããªãã®ãœãªã¥ãŒã·ã§ã³ã§ã¯ããå°éå ·ãšã¹ãããã®éã«äžè¬çãªé¢ä¿ã欲ããã ããã®å Žåã¯ãå ¥åããå¿ èŠãå°ãªããªããŸãããããã¯çŽ æŽãããããšã§ãã ããããäž¡æ¹ãè¿œå ããã ãã§ããããšæã£ãŠããäžæ¹ã§ãAPIãµãŒãã§ã¹ãæ¡åŒµããããŠããããã«æããŸãïŒåãããšãããŸããŸãªæ¹æ³ã§å®è¡ã§ããŸãïŒãããããŸããã
ç§ã¯æ¬åœã«interface ComponentDef<T>{ props: {} }
ãæžãçããŠããããç§ã®ãšã¯ã¹ããŒãã®ãããããšäžŠã¹ãå¿
èŠã¯ãããŸããã Svelteã¯ãReactãšæ¯èŒããŠãå
¥åãããæåãæžããã®ã«éåžžã«åªããŠãããããã¯äžæ©åŸéããããã«æããŸãã ç¹ã«ããã¹ãŠã®ãšã¯ã¹ããŒãã®ã¿ã€ããå°éå
·ã«è€è£œããå¿
èŠããããŸãããããã¯é¢çœããããŸããïŒãããŠé »ç¹ãªåé¡ã«ã€ãªããããšã«ãªããŸãïŒã
@halfnelsonã®èãæ¹ã奜ãã§ãã ãšã¯ã¹ããŒãã¯å°éå ·ãšããŠæ€åºããå¿ èŠããããŸãã ã¢ãžã¥ãŒã«ãäžåºŠã¯ã©ã®ããã«èŠãããããããŸãã
ãã1ã€ã®ç°¡åãªæ¹æ³ã¯ãé¢é£ããåé¡ã®ããã€ãã§èªãã ãã®ã§ããJSDocã³ã¡ã³ãã䜿çšããŠã @template
ãªãã·ã§ã³ãªã©ãå
¥åã«åé¡ãçºçããããšã¯ãããŸããã
JSDocã«å¯ŸããŠãªãŒãã³ãã€ã³ããä¿ã€å¿
èŠããããŸããïŒHTMLå
ã§JSDocã䜿çšããå Žåã§ãïŒãWebStormãŸãã¯VS Codeã®ã©ã¡ãã䜿çšããå Žåã§ããTypeScriptãšããŠè¡šçŸã§ããªãããšãèŠåããå¿
èŠããããŸãã ããšãã°ã true
ã¿ã€ããå®è£
ããŠããŸããã ã€ã³ããã¯ã¹ã¿ã€ãã¯å®è¡ããªããšç¢ºä¿¡ããŠããŸãã æãåºããšã Record<keyof X, any>
ãæãŠãŸããã ç§ã¯ããã§å£ã«ã¶ã€ããç¶ããŸãã @template
ã¯æ©èœããŸããããããªãå¶éãããŠããŸããã ãŸããIDEã«ãã£ãŠãåäœãç°ãªããšæããŸãã
ãžã§ããªãã¯åãæž¡ãïŒjsxïŒelementã¯ãæå¹ãªsvelteãã³ãã¬ãŒãæ§æã§ã¯ãªããããç§ã«ã¯äœ¿çšã§ããŸããã ãžã§ããªãã¯ã¯ããããã£ã«ãã£ãŠé§åãããããããããå¿
èŠãããŸãããã¹ããã/ã€ãã³ãã®ã¿ã«äŸåãããžã§ããªãã¯ãå°å
¥ããæ¹æ³ã¯èããããŸããã ããããå
¥åããããã£ã«ãã£ãŠé§åãããå ŽåãTSãæšæž¬ãããããªæ¹æ³ã§svelte2tsx
ã³ãŒããçæã§ããããããžã§ããªãã¯ã¹ãjsxèŠçŽ ã«æž¡ãå¿
èŠã¯ãããŸããã
ã¿ã€ãã³ã°ã®ãªãŒããŒãããã«ã€ããŠïŒããã¯æ£ããã§ããããžã§ããªãã¯ã¹ã䜿çšããããã€ãã³ã/ã¹ããããæ瀺çã«ã¿ã€ããããããå Žåã«ã®ã¿å¿
èŠã«ãªããŸãã çè«çã«ã¯ãããããã¹ãŠãèªåãã¡ã§æšæž¬ããããšã¯ã§ããŸããããããå®è£
ããã®ã¯éåžžã«é£ãããšæããŠããŸãã ãã®ãããªå®è£
ãé£ããåé¡ã®äŸãšããŠã¯ãïŒ263ã®ãããªé«åºŠãªã¹ãããã·ããªãªã®ãµããŒãããèãããããã¹ãŠã®ã³ã³ããŒãã³ãã€ãã³ãã®åéããããŸãïŒãŠãŒã¶ãŒãcreateEventDispatcher
ã®ã¿ã䜿çšããå Žåã¯ç°¡åã§ãããé¢æ°ãã€ã³ããŒãããããšãã§ããŸãïŒã createEventDispatcher
ã®ãã®ãã©ããããŸãïŒã
äžè¬ã«ã人ã ããããã®1ã€ã ããå®çŸ©ããä»ã®ãã®ã¯å®çŸ©ããããªããšããç¶æ³ã¯ãããããããšæããŸãããã®ãããSvelteã®ãã¿ã€ãã¬ã¹ã粟ç¥ãç¶æããããã«ãããŸããŸãªãªãã·ã§ã³ããã¹ãŠæäŸããå¿ èŠããããããããŸããã
ããã¯æ¬¡ã®ããšãæå³ããŸãïŒ
ComponentDef
ã¯ãå¿
èŠã«å¿ããŠãã¹ãŠã1ã€ã«ãŸãšãããã®ã§ããComponentEvents
ã¯ã€ãã³ãã®å
¥åå°çšã§ãComponentSlots
ã¯ã¹ãããã®å
¥åå°çšã§ã<script generic="T">
ã®ãããªæ§é ComponentEvents/ComponentSlots/generic="T"
ã®çµã¿åãã@shirakaba JSDocã¿ã€ãã®ãµããŒãã¯ãã¿ã€ãã¹ã¯ãªããã®ããã«æ©èœãè±å¯ã§ããå¿ èŠã¯ãããŸããã å€ãã®äººãããã䜿ã£ãŠãžã§ããªãã¯ã³ã³ããŒãã³ããå ¥åããã®ã§ã¯ãªãããšæããŸãã ãŸããtypescriptã®èšèªãµãŒãã¹ã䜿çšããŠãããããå€ãã®é«åºŠãªã¿ã€ããtypescriptãã¡ã€ã«ããç°¡åã«ã€ã³ããŒãã§ããŸãã
ã¹ãããå°éå ·ã®ã¿ã€ããã§ãã¯ã«ã€ããŠãç§ã¯ããã€ãã®ããã¯ãæã£ãŠããŸããããããè¯ãéçºè äœéšã«ã€ãªãããã©ããã¯ããããŸããã ãã®ãããªãŠãŒã¶ãŒã¿ã€ãã®ã³ã³ããŒãã³ãã®å ŽåïŒ
interface ComponentDef {
slots: { default: { item: string } }
}
ã¯ã©ã¹ãçæã§ããŸã
class DefaultSlot extends Svelte2TsxComponent<ComponentDef['slots']['default']>{ }
ããã©ã«ãã®ã¹ããããã«å€æããŸã
<DeafaultSlot />
ïŒãŠãŒã¶ãŒãšããŠãã£ã€ã ã鳎ããã ãã§ãïŒTypeScriptã§äœæ¥ããŠããéããšã«ããå€ãã®ããšãããªããã°ãªããªãã®ã§ãç§ã«ãšã£ãŠäœåãªã¿ã€ãã³ã°ã¯åé¡ã§ã¯ãããŸããã
ã€ã³ã¿ãŒãã§ã€ã¹ãšgeneric
ããããã«ã€ããŠã¯ãå€æ°ãã³ã³ã·ã¥ãŒããŒã«ã®ã¿å
¬éãããå ŽåããããããããããããµããŒãããã®ã¯DXã®æ¹ãé©ããŠããŸãã ãããããã®ç¹ã§ã generic="T"
export type T
ããµããŒãããããšã¯å¯èœã§ããããïŒ
ããã¯ç¡å¹ãªTSæ§æã§ããã人ã ãæ··ä¹±ãããå¯èœæ§ããããŸãã ãŸããè¿œå ã®å€æã¹ããããå®è¡ããå¿ èŠããããŸããããã¯ãSvelteã³ã³ããŒãã³ããã³ã³ãã€ã«äžå¯èœãªç¶æ ã®å Žåã«ã¯å®è¡ãããŸããã ãã®å Žåãlanguage-toolsã¯ã¹ã¯ãªããã«ãããã®ã«ãã©ãŒã«ããã¯ããã¹ã¯ãªããã«ã¯ãã®ç¡å¹ãªæ§æãå«ãŸããŸãã ã ããç§ã¯ããã«å察ã§ãã
ããããŸããã é·åŒãããšã¯ãããŸããããæ§æãç¡å¹ã§ãããããæªå®çŸ©/äžæãªã¿ã€ãããšã©ãŒãå€ãã®ã§ããããã TypeScriptã®ã³ã³ãã€ã©ã2ã€ã®ã±ãŒã¹ãã©ã®ããã«åŠçãããããããªãã®ã§ãç§ã¯å°ããŠããŸãã script
ã¿ã°ã«ã«ã¹ã¿ã å±æ§ãè¿œå ããããšã«å¯ŸããŠãç¹ã«ãgenericãã®ãããªäžè¬çãªååã§äºçŽããã ãã§ã:)
å šäœãšããŠãç§ã«ãšã£ãŠãããã¯äŸ¿å©ã§ãããã³ã³ããŒãã³ãã䜿çšãããšãã«ãŠãŒã¶ãŒã«ãšã¯ã¹ããŒããããå€æ°ãå ¥åããããã«åŒ·å¶ããããšã¯è¯ãããšã§ãïŒããèªã¿ãããã³ãŒãïŒã
export type T;
ãšå
¥åãããšãTSã¯æ§æãšã©ãŒãã¹ããŒããŸãã ãŸããå¶çŽãå®åŒåããæ¹æ³ã¯ïŒ export type T extends string;
ã¯ãããå€ãã®æ§æãšã©ãŒãã¹ããŒããŸãã ã«ã¹ã¿ã å±æ§ã«å¯ŸããäºçŽã¯å®å
šã«ç解ããŠããŸãããæãæ··ä¹±ã®å°ãªãæ¹æ³ã ãšæããŸãã ä»ã®æ¹æ³ã¯ã T1
ãT2
ã®ãããªäºçŽæžã¿ã®ååã䜿çšããããšã§ãããããã¯ååãªæè»æ§ããããŸããïŒå¶çŽãè¿œå ããæ¹æ³ã¯ïŒïŒã
å¥ã®æ¹æ³ã¯ã ComponentDef
ãä»ããŠã³ã³ããŒãã³ãå
šäœãå
¥åããããšã§ããããã§ã¯ãæåã®æçš¿ã®äŸã®ããã«ããžã§ããªãã¯ãèªç±ã«è¿œå ã§ããŸãã ããããããã«ã¯ããå€ãã®ã¿ã€ãã³ã°ãç ç²ã«ãªããŸãã
ç§ã«ãšã£ãŠã人ã
ã¯ããã«ã€ããŠéåžžã«ç°ãªãæèŠãæã£ãŠãããããå€ãã®ãªãã·ã§ã³ãã¬ã€ã¢ãŠãããããšïŒ ComponentDef
ãå±æ§ãšããŠã®äžè¬çãªå°éå
·ã ComponentEvents
ãšå
¥åããã ãïŒãæãæè»ã§ããããšãè°è«ããæããã«ãªããŸã圌ãã¯åãããšãããããŸããŸãªæ¹æ³ã玹ä»ããŸããã圌ãã®ã»ãšãã©ã幞ãã«ããŸãã
ç§ã¯ãããèŠéãããããããŸããããããããªãã·ã§ã³ã«åå²ããŠããŸããïŒ
<script>
import type { Foo } from './foo';
export let items: Foo[];
interface ComponentSlots<T> {}
interface ComponentEvents<T> {}
</script>
ã»ãšãã©ã®å Žåãå ¥åã®ãªãŒããŒããããæžããŸããïŒ
ã¯ããããã¯å¯èœã§ãã
@dummdidummã¯ããã®éã«interface ComponentSlots {}
ïŒãžã§ããªãã¯ã¹ã®ãµããŒãã®æç¡ã«ãããããïŒã®ãµããŒãã«åãçµãããšã¯å¯èœã§ããïŒ ãããšãããããå°å
¥ããããšã¯ãããã§è°è«ãããŠããããšãšççŸããã§ããããïŒ
ããã§ã¯ãããŸããããå®è£ ãç¶è¡ããåã«ãææ¡ããããœãªã¥ãŒã·ã§ã³ã«ã€ããŠã³ãã¥ããã£ãä»ã®ã¡ã³ããããããå€ãã®ãã£ãŒãããã¯ãåŸãããã«ããŸãRFCãäœæããããšæããŸãã åæãåŸããããããããã®å®è£ ãéå§ããŸãã
@joelmukuthuãšããã§ããªãã€ã³ã¿ãŒãã§ãŒã¹ããµããŒããããã®ã§ããïŒ ã¹ãããã®åæšè«ã匷åããŸããããããã§ãããŸããããªãå ŽåããããŸããïŒ ãããããªããç§ã¯ããªãã®ã±ãŒã¹ãèããŠèå³ããããŸãã
ãã®ãããã¯ã«é¢ããRFCãäœæããŸããïŒ https ïŒ//github.com/sveltejs/rfcs/pull/38
APIã«é¢ããè°è«ã¯ããã§ç¶ããããã¹ãã§ãã
@dummdidummå¿çãé ãããšããè©«ã³ããŸãã ç§ã®ãŠãŒã¹ã±ãŒã¹ã§ã¯ãå®éã«ã¯ãžã§ããªãã¯ã¹ã®ãµããŒããå¿ èŠã§ããããšã«æ°ã¥ããŸããã ã¹ãããã®åæšè«ã¯éåžžã«ããŸãæ©èœããŸãïŒ
ããã¯å·šå€§ã§ãããïŒ ç§ã¯çŸåšãã¹ãããã®ããããã£ã䜿çšããããšã¯åžžã«äœã§ãããããšãæ²ããã§ããŸãã
å¥åŠãªããšã«ã䜿çšããã³ã³ããŒãã³ãããããžã§ã¯ãå ã«ãããTSã䜿çšããŠããå Žåããã®æç¹ã§ã¹ãããã¿ã€ãã¯éåžžã«ããŸãæšæž¬ã§ããŸãã
ããããç§ã¯ããã§ééã£ãçšèªã䜿çšããŠããŸã...ãŸãã¯ããŸãããã°ç§ã¯äœãééã£ãããšãããŸããã
ç§ããããããšã®äŸïŒ
`` `html
{option.myLabelProp}
ããããŸãããã¯ããçŸæç¹ã§ã¯ããã¯äžå¯èœãªã®ã§ã any[]
ã«ãã©ãŒã«ããã¯ããå¿
èŠããããŸãã ããã§string[]
ããèš±å¯ãããªãå Žåãã¹ãããã¯string
ãšå
¥åãããŸããããã¯ããã¿ã€ããæšæž¬ã§ããããšããæå³ã§ãã
MarkVolkmannã«ãããSvelteandSapper in Actionãã§åºäŒã£ãã¿ã€ããã§ãã¯ã³ã³ããŒãã³ãã®äžæçãªè§£æ±ºçã¯ã$$ propsãšäžç·ã«Reactprop-typesã©ã€ãã©ãªã䜿çšããããšã§ãã
ããã¯ãããšãã°Todoã¢ã€ãã ã®ã³ãŒãã§ãã
import PropTypes from "prop-types/prop-types";
const propTypes = {
text: PropTypes.string.isRequired,
checked: PropTypes.bool,
};
// Interface for Todo items
export interface TodoInterface {
id: number;
text: string;
checked: boolean;
}
PropTypes.checkPropTypes(propTypes, $$props, "prop", "Todo");
Todoã®å°éå ·ãæ€èšŒããäœãããªãã«ãªã£ãŠãããšãšã©ãŒãçºçããäžæ¹ã§ãVsCodeã§éçåãã§ãã¯ãšèªåè£å®ãè¡ããããã«ãTodoã¢ã€ãã ã®ã€ã³ã¿ãŒãã§ã€ã¹ãå¿ èŠã§ãã ããã¯ãäžèšã§å®çŸ©ããã€ã³ã¿ãŒãã§ã€ã¹ã䜿çšããŠå®çŸãããŸãã ããã®æããã§é倧ãªæ¬ ç¹ã¯ãããã«éè€ããã³ãŒããå¿ èŠãªããšã§ãã propTypesãªããžã§ã¯ãããã€ã³ã¿ãŒãã§ã€ã¹ãå®çŸ©ããããšã¯ã§ããŸããããã®éãåæ§ã§ãã
ç§ã¯ãŸã javascriptã䜿ãå§ããŠããã®ã§ããããééã£ãŠããå Žåã¯ä¿®æ£ããŠãã ããã
åãã§ãã¯ã¯ãå®è¡æã®éçãã§ãã¯ãšpropsåãã§ãã¯ã®äž¡æ¹ã§ãçç£çãªã³ãŒãããŒã¹ã«å¿ é ã ãšæããŸãã
ïŒã€ã³ã¿ãŒãã§ãŒã¹ã¯context = 'module'ã§å®çŸ©ããããããã³ã³ããŒãã³ãã®ããã©ã«ãã®ãšã¯ã¹ããŒããšäžç·ã«ãšã¯ã¹ããŒãã§ããŸãããç°¡æœã«ããããã«ãã®éšåã¯çç¥ãããŠããããšã«æ³šæããŠãã ããïŒ
ç·šéïŒå°éå ·ã®æ€èšŒä»¥å€ã®ç®çã§ãããè©Šããããšã¯ãããŸãããã¹ããã/ã€ãã³ãã§ãæ©èœãããã©ããæããŠãã ããïŒ
æãåèã«ãªãã³ã¡ã³ã
ããããç§ã¯ããã§ééã£ãçšèªã䜿çšããŠããŸã...ãŸãã¯ããŸãããã°ç§ã¯äœãééã£ãããšãããŸããã
ç§ããããããšã®äŸïŒ
`` `html
{option.myLabelProp}