sveltejs / language-tools

The Svelte Language Server, and official extensions which use it
MIT License
1.23k stars 196 forks source link

Support @ts-ignore comments in template markup #1026

Open madeleineostoja opened 3 years ago

madeleineostoja commented 3 years ago

Is your feature request related to a problem? Please describe. Since svelte can't (yet?) support typescript expressions in component template markup, it's impossible to provide typings/coercions/etc in template logic blocks. This results in seas of red warnings and errors in the editor and svelte-check.

Describe the solution you'd like Assuming giving Svelte full typescript support in markup is either not going to happen or not happening any time soon, it would at least be nice to support @ts-ignore HTML comments to skip typescript warnings for the following line of code.

Describe alternatives you've considered The only real alternative is to disable typescript diagnostics in language-tools entirely, which is obviously less than ideal

dummdidumm commented 3 years ago

This is tricky if not impossible for some situations, for example if you have your attributes spread out over multiple lines. @ts-ignore only works for the next line, and html comments within the < > of a tag are invalid. What is the sea of errors you talk about specifically? Can this be solved by more explicit typing up front?

madeleineostoja commented 3 years ago

Hmm that’s fair, I hadn’t thought of attributes spreading over multiple lines. That would make @ts-ignore comments fragile and unintuitive.

Happy to just close this and hope for type support in template markup instead

lovasoa commented 2 years ago

I use this nasty trick to disable type checking of a single attribue :

<script lang="ts">
    const notypecheck = (x:any)=>x;
</script>

<MyComponent {...notypecheck({
    attribute:  value
}) />
rogadev commented 1 year ago

I use this nasty trick to disable type checking of a single attribute :

<script lang="ts">
  const notypecheck = (x:any)=>x;
</script>

<MyComponent {...notypecheck({
    attribute:  value
}) />

How would you do that for something like this:

{#each columns as blok}
  <div class="flex-auto px-6">
    <StoryblokComponent {blok} /> <!-- (property) StoryblokComponentProps.blok: SbBlokData
      Type 'string' is not assignable to type 'SbBlokData'.  -->
  </div>
{/each}

And if a method of doing so exists, is it easier than:

{#each columns as blok}
  <div class="flex-auto px-6">
    <!-- @ts-ignore -->
    <StoryblokComponent {blok} />
  </div>
{/each}
dummdidumm commented 1 year ago

If this would be implemented, it would be through a <!-- @ts-ignore --> comment. Since comments cannot be placed within the tag itself, the question is what the more intuitive/wanted behavior here is:

<!-- @ts-ignore -->
<ComponentThatHasError
  {propThatHasError}
/>

should the error from propThatHasError also be ignored, or only the error from <ComponentThatHasError? My feeling is that everything inside the component should be ignored, because

Thoughts welcome

madeleineostoja commented 1 year ago

That would certainly be the intuitive behavior, but it also feels fragile? I don’t know implementation details though.

I guess the wider question is has there been any momentum on allowing ts in template expressions? That would make this issue kind of moot

dummdidumm commented 1 year ago

Good point, with TS inside template expressions you could do casting instead, which would probably solve this for 90% of use cases. What's left would be things like silencing errors like "don't know this component" or "this component/element doesn't have prop X", which are probably rare.

crushingCodes commented 1 year ago

I couldn't get the suggestion above to work, but luckily the component was my own, so i was able to get around it using the following:

MyComponent.svelte

<script lang="ts">
    import type { IThing } from '$lib/server/types';

    export let value: unknown;

    const thing: IThing = value as IThing;
</script>

Consumer.svelte

<MyComponent value={value} />
LorenzoBloedow commented 1 year ago

I have a suggestion: we could prefix attributes with ts-ignore- or just use the directive ts-ignore-all to ignore the entire component.

nikonikoniko commented 4 weeks ago

I have managed to sneak in a @ts-ignore in like this:

<Input
  type="file"
  multiple
  {...attrs}
  {...{
    ...{} 
    /* @ts-ignore */
  }}
  bind:files={$formData.file}
/>

I used this to replace the useful trick from @lovasoa