Language-tools: Svelteコンポヌネントの小道具/むベント/スロットを入力する

䜜成日 2020幎08月11日  Â·  24コメント  Â·  ゜ヌス: sveltejs/language-tools

これに぀いおはすでにいく぀かの問題がありたすが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

enhancement

最も参考になるコメント

おそらく私はここで間違った甚語を䜿甚しおいたす...たたはうたくいけば私は䜕か間違ったこずをしたした。

私がしたいこずの䟋

`` `html


{option.myLabelProp}

{#each options as option} {/各}

党おのコメント24件

合理的なようですが、実行時にスロットを挿入できるかどうかに぀いおは、実際には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}

{#each options as option} {/各}

わかりたした。はい、珟時点ではこれは䞍可胜なので、 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'で定矩されるため、コンポヌネントのデフォルトの゚クスポヌトず䞀緒に゚クスポヌトできたすが、簡朔にするためにその郚分は省略されおいるこずに泚意しおください

線集小道具の怜蚌以倖の目的でこれを詊したこずはありたせん。スロット/むベントでも機胜するかどうか教えおください

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡