Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeScript support #1639

Closed
3 tasks
tbillington opened this issue Aug 8, 2018 · 61 comments
Closed
3 tasks

TypeScript support #1639

tbillington opened this issue Aug 8, 2018 · 61 comments
Labels

Comments

@tbillington
Copy link

This is intended to be a tracking issue for TypeScript support. Feel free to edit.

  • Writing TypeScript in <script> tags in components.
  • Importing TypeScript code into Svelte files (including editor support?!).
  • Importing Svelte components into TypeScript code.

Some of these are partially supported now. I have been able to import Svelte components into TS and manually declaring their type using rollup-plugin-typescript. I've also been able to import TS code into Svelte components, however their is no support for suggestions/error highlighting on the editor side (from what I've seen).

@tbillington tbillington changed the title Support for using Svelte with TypeScript Svelte TypeScript support Aug 8, 2018
@GarrettGeorge
Copy link

For <script> tags we could use inspiration from <style> tags which use the lang attribute.

Ex:

<script lang="ts">
  export default {...}
</script>

@Kiho
Copy link
Contributor

Kiho commented Aug 9, 2018

@tbillington First item is not supported at all, however item 2 works fine with VS Code Svelte Plug-In and you can adjust behavior little bit with root level tsconfig.json. For item 3, I doubt it but if you really need typing support in ts modules, then you can possibly make it work with pre-process like this repo.
I was not able to make work that with arrow function though....

@colah
Copy link

colah commented Aug 12, 2018

This is only tangentially related, but I sometimes wish I could give TypeScript-like type specifications for my svelte components data. I'm not exactly sure why -- it's not like I frequently pass in the wrong type of data. I guess some plausible benefits are:

  • When I start writing a component, I'd like to get the data it will take clear in my head. Normally I do this by including default values for all the data properties, but sometimes there are things I can't make a default value (eg. a large object that will get generated elsewhere).
  • I'd like to make it easy to determine what the valid inputs to my component are.

@tbillington tbillington changed the title Svelte TypeScript support TypeScript support Sep 17, 2018
@DrSensor
Copy link

@fjorgemota
Copy link
Contributor

fjorgemota commented Oct 25, 2018

@DrSensor I'm not sure if this fixes the issue.

I mean, it's very easy to use that package to just transpile the typescript code to valid javascript and let the Svelte compiler work with that...

BUT, it's not easy IMO to do the semantic check of the code, which Typescript is able to do.

For example...How to type-check this code?

<p>This is a top-level element.</p>
<Nested/>

<script>
	import Nested from './Nested.html';

	export default {
		components: {
			Nested
		}
	};
</script>

That type of thing is definitely not easy to do with Typescript semantic checkings on svelte-process, IMO..

By the way...A good suggestion would be to check this PR: vuejs/vetur#94 - which adds Typescript support to Vue for usage with VSCode..

@fjorgemota
Copy link
Contributor

Hey.

I've been thinking about how to add support for Typescript (and probably other languages that compiles to Javascript) on Svelte and I concluded a few things about it:

  • First, adding support for transpilation (without any semantic checking) is easy by using Svelte Preprocess, at least for code between <script></script> HTML tags (i.e it's not that easy to support code on event handlers, conditions, loops and tags, for example, because this would need the parsing of the Svelte code in the same way that Svelte compiler does);
  • Second, adding semantic checking (like type-checking, which Typescript does) is not that easy, because:
    • We would need to parse Svelte components to provide type-checking specifically for nested components...That would include discovering methods that the nested component includes, for example;
    • We have no way actually to parse Svelte conditions, loops, tags and event handlers (on:click) without reinventing the wheel (i.e without writing code specifically to that, because there are no public methods that the Svelte compiler provides to do that), so type-checking on these places are out of question;
    • We would need to parse a few things like ref:<id> attributes and type refs attribute accordingly;
    • Even by solving these two points, the type-checking would not be very complete because the code generated by Svelte is not typescript itself, so if Svelte changes to v2 with a few breaking changes (i.e change of the name of a few methods), for example, we would need to adapt the definitions used in the checking accordingly or the compilation would continue to pass, but with runtime errors obviously.

For now, I see a few possibilities:

  • Expose a few public ways to access the AST seen by the compiler, so it's easy to detect (what should be) javascript expressions on the Svelte component;
  • In the future, publish a way to generate typescript code directly from the svelte compiler, so all the hard work would be done by the typescript checker (this is basically generate jsdoc/typescript/flow #58);

Yeah...it's not exactly a simple thing to do....

@mindplay-dk
Copy link

I've also been able to import TS code into Svelte components, however their is no support for suggestions/error highlighting on the editor side (from what I've seen).

@tbillington I'd be happy if I could just get that to work - I'd be able to keep the complex code in services in TypeScript, and call into those services from the Svelte app, which would then solely act as the UI and a sort of lightweight "controller" that dispatches service methods.

While I'd love to have type safety everywhere, I'm not sure it's extremely necessary on the UI side, since Svelte is quite declarative - if I can keep any complex stuff out of Svelte and in TypeScript, the coupling between the Svelte app and services could be fairly thin, so it doesn't worry me much.

Having to currently choose between Svelte with plain JS (ugh) and TypeScript without Svelte, there isn't really any choice - I'm afraid a lot of TypeScript users feel the same. I'm not fond of React or JSX, but it has TypeScript support, so, sadly, there isn't much of a choice at the moment...

@from-the-river-to-the-sea

Throwing in my 2 cents: I'm a long-time Polymer user who is looking for an alternative, now that Polymer is more or less dead with no good next step. I quite like Svelte and it seems like a natural progression from Polymer, but the lack of first-class TypeScript support is the primary thing stopping me from using it.

@kylecordes
Copy link

The big challenge here is that really good TypeScript support is not a mere add-on. Rather, a top-notch TypeScript experience would come from pervasively designing a future version of Svelte (or any other similar library/framework/compiler/tool) from the ground up this way. It would perhaps require that Rich deeply embrace TypeScript, and (if other libraries have been any guide) take a few iterations to get really good. The results would probably end up working great with TypeScript, but contain things that feel unnecessary or a little awkward for someone consuming them from plain JavaScript.

(TypeScript and JavaScript are technically perfectly compatible, but there is a bit of a cultural gap.)

Making Svelte be really TypeScripty is also a bigger lift than, for example, the TypeScript-centric design of Stencil. The latter benefits from using VDOM/TSX (TypeScripty JSX), for a good developer experience, while more work would be needed to integrate the Svelte template compiler into the TypeScript compiler phase system somehow, to create similar goodness here.

@Rich-Harris
Copy link
Member

Svelte 3 is being designed with TypeScript support in mind. I'm not enough of an expert in TypeScript to know exactly what's involved in getting things like auto-complete working inside templates, but the design is fundamentally much more TS-friendly than Svelte 2.

I'll be chatting with folks in the near future about what'll be involved in getting first-class TS support into Svelte, and I have a good feeling about where we'll be a couple of months from now. I'm a TS devotee myself (Svelte itself is written in TS) and I'd love to be able to use it in my own components, so know that it is a high priority!

@mindplay-dk
Copy link

@Rich-Harris thanks for the update! that is great news! 😄

@dgreene1
Copy link

I’d be interesting in using Svelte once TS support is more out of the box. Stencil provides it already, but Svelte has more usage.

@fjorgemota
Copy link
Contributor

How is this going to work? Is there any news related to this issue?

I would like to know if we're going to get type checking support in Svelte components, for example, and if that would depend directly on editor support or some type of flag passed to svelte compiler itself (?), specifically.

@stereosteve
Copy link

There was some discussion in the discord a week ago about hooking into the TypeScript compiler API... but that would be no small task.

A possibly more 💩solution would be to support both html-based and javascript/typescript-based svelte files. A typescript file could export html and css template literals... it'd be easy for a tool to convert from one to the other.

For example the flight booker example:

const tomorrow = new Date(Date.now() + 86400000);

let start = [
    tomorrow.getFullYear(),
    pad(tomorrow.getMonth() + 1, 2),
    pad(tomorrow.getDate(), 2)
].join('-');

let end = start;
let isReturn = false;

// reactive declarations would require let
$: let startDate = convertToDate(start);
$: let endDate = convertToDate(end);

function bookFlight() {
    const type = isReturn ? 'return' : 'one-way';

    let message = `You have booked a ${type} flight, leaving ${startDate.toDateString()}`;
    if (type === 'return') {
        message += ` and returning ${endDate.toDateString()}`;
    }

    alert(message);
}

function convertToDate(str) {
    const split = str.split('-');
    return new Date(+split[0], +split[1] - 1, +split[2]);
}

function pad(x: any, len: number) {
    x = String(x)
    while (x.length < len) x = `0${x}`;
    return x;
}

// here there could be template tags e.g. svelteCSS
export const css = /* css */`
select, input, button {
    display: block;
    margin: 0.5em 0;
    font-size: inherit;
}
`

// here there could be template tags e.g. svelteHTML
export const html = /* html */`
<!-- https://github.com/eugenkiss/7guis/wiki#flight-booker -->
<select bind:value={isReturn}>
	<option value={false}>one-way flight</option>
	<option value={true}>return flight</option>
</select>

<input type=date bind:value={start}>
<input type=date bind:value={end} disabled={!isReturn}>

<button
	on:click={bookFlight}
	disabled="{isReturn && (startDate >= endDate)}">book</button>
`

TypeScript does complain that A label is not allowed here about the reactive declarations... but other than that you'd get all the nice editor features and whatnot.

@kesla
Copy link

kesla commented Apr 22, 2019

@Rich-Harris what's the status of TS support in svelte now that v3 has been released? Could this issue be closed?

@ihodes
Copy link

ihodes commented Apr 22, 2019

It looks like not quite yet.

Sort of, via preprocessing, but you won't get any real benefit from it at present. There are two barriers: the compiler itself needs to become TS-aware, and we need to teach editors like VSCode how to typecheck inside <script> blocks.

It's very much on the radar (I'm a TS convert, personally — Svelte itself is written in TypeScript), we just need to get round to it. The version 3 rewrite was largely about laying the foundations for TS support.

@tbillington
Copy link
Author

@kesla Not being rude, just curious why you think this issue should be closed now? How you use typescript and svelte hasn't really changed since this issue was created. From what I hear v3 is intended to make using typescript easier but it's still on the roadmap.

@dgreene1
Copy link

You could probably check out the vuetify codebase since that extension does some TypeScript compilation of html files (well, .vue files)

@kesla
Copy link

kesla commented Apr 23, 2019

@kesla Not being rude, just curious why you think this issue should be closed now? How you use typescript and svelte hasn't really changed since this issue was created. From what I hear v3 is intended to make using typescript easier but it's still on the roadmap.

I thought that maybe TS support exists in v3 already, in which case this issue could be closed. Thank you @ihodes for finding an update on the state of TS support in v3!

@kylecordes
Copy link

I suggest that either this issue or some replacement issue be kept open until there is gloriously complete TypeScript support in Svelte. Such complete support that it works out of the box upon initial install, without even having to ask or adjust with any settings. So complete that the property interactions from one component to another are type-checks real time in at least one mainstream IDE, and in the online REPL. That even the online REPL be TS by default.

(Though I guess that might be something not so much "TypeScript support, but more like "pervasive TypeScript by default, with optional JavaScript support”.)

@PaulMaly
Copy link
Contributor

For all interested, we're making experiments on TS support in script part of Svelte components using svelte-ts-preprocess. Any help is welcomed!

@dlants
Copy link

dlants commented Apr 24, 2019

One thing worth considering for typescript and svelte is how type narrowing interacts with templates.

In the project I spend most of my type working on, we make heavy use of discriminated unions. These work nicely with VDOM frameworks, since type information flows naturally through your render function declaration:

type Page: {
  location: 'home'
} | {
  location: 'user',
  userId: string
}

render() {
  const page: Page = this.props.page
  switch (page.location) {
    case 'user':
      return <div>{page.userId /* <- OK since the switch narrows the type. */}</div>
  }
}

I think this is going to be very challenging to make work across svelte template directives, and is one reason why using typescript to define svelte components (using something like JSX or hyperscript) may have an advantage.

@mindplay-dk
Copy link

A possibly more 💩solution would be to support both html-based and javascript/typescript-based svelte files. A typescript file could export html and css template literals... it'd be easy for a tool to convert from one to the other.

@stereosteve this isn't necessarily a 💩 idea at all?

If you added html and css template functions, these could tag the content for preprocessing, e.g.:

import { html, css } from "svelte";
// ...
html`...`;
css`...`

The html and css template functions would be just placeholders that enable the pre-processor to identify those areas of the TypeScript source file.

I'm +/- on this vs the current approach - both are supersets of an existing syntax and are just a little bit hocus-pocus in that way... I mean, a Svelte file is valid HTML, but it doesn't work without the preprocessor - what you're proposing is valid TypeScript, but it doesn't work without the preprocessor. The only real difference is where you start and in which direction you depart from the parent syntax.

@pyoner
Copy link
Contributor

pyoner commented Apr 26, 2019

Hi,
check out the typescript template for Svelte v3 https://github.com/pyoner/svelte-ts-template based on https://github.com/PaulMaly/svelte-ts-preprocess

@alshdavid
Copy link

alshdavid commented May 1, 2019

I just picked up Svelte and love it.

Eagerly awaiting official TypeScript support so I can use, demo and recommend it!

@purpledrgn
Copy link

purpledrgn commented May 7, 2019

@mindplay-dk its a bit of a 💩 solution because it really kills part of the dream of having it being very intuitive and simple to pickup.

Having it look like classic html file with script and css that's magical is not the only pro to svelte but it is one of it's best parts. I'd rather the integration just not care for TS in the svelte files themselves (or be very basic), I can just split the complex logic out into proper ts files.

As a typescript developer I don't exactly particularly get any usefulness out of the (overly complex) React types when using React. External types in general are not particularly useful outside just hinting (which I won't lose sleep over outside of enums), its your own internal types that provide the biggest benefit.

And don't get me wrong template functions (and other forms of annotations) are fine as a tool, but they're really the monkey wrench of desperation. If someone came and told me they came up with a elegant way where we don't have to leverage them at all, I would be very happy with that variation.

@purpledrgn
Copy link

purpledrgn commented May 7, 2019

On the topic of typescript and types, it would probably be better (even for vanilla js) if svelte had a way to specify a concrete name for the component defined in the file. A declarative way like component Hello; or if we want to be html-ish <!component Hello> or such would be fine.

Importing from default is more annoying then just having this since when you have a name simply typing the name will tip the editor of what you want (no need to write imports yourself). Editors can usually be setup to not even ask for the really obvious ones (single option cases).

In addition its very good for refactoring and general consistency (in particular during prototyping). If you import a Hello component by name instead of default then you can always refactor it to a Welcome component and everything would still remain consistent; versus having Hello in some places, Welcome in others, and so on.

@kylecordes
Copy link

An alternative point of view: This would mean another different way of saying the same thing (name of the component), and then eventually needing tools to keep everything matching. We already have the name of the thing in the file name, why expend another line of boilerplate in every component file restating the same name?

@lgirma
Copy link

lgirma commented May 30, 2019

Coming from a react-typescript (TSX) world and this lack of typescript support is what is holding me back from adopting it in a production use.

Mostly, refactoring has been a huge pain.

@KleinMaximus
Copy link

https://github.com/kaisermann/svelte-preprocess

@jerrygreen
Copy link

@PaulMaly
Copy link
Contributor

PaulMaly commented Jun 8, 2019

@jerrygreen Ok, TS not supported in templates and? Is TS supports templates? No. I believe you able type check all your code in script tag if all assignments will be in callbacks.

@alex7kom
Copy link

alex7kom commented Jun 9, 2019

@PaulMaly TS supports JSX, for example https://www.typescriptlang.org/docs/handbook/jsx.html. I believe this is the kind of TS support everybody wants for Svelte templates.

@hronro
Copy link

hronro commented Jun 9, 2019

@alex7kom Yes, but I believe this kind of support need some works from TypeScript team.

@furozen
Copy link

furozen commented Jun 9, 2019

Does somebody know how to fix typing error (svelte 3.4.4):
Error:(2, 23) TS2724: Module '"svelte/store"' has no exported member 'Writable'. Did you mean 'writable'?
happens for row:
import {derived, get, Writable, writable} from 'svelte/store';
to reproduce change imports there:
https://github.com/furozen/svelte-todomvc/blob/master/src/TodoMVCLogic.ts

@PaulMaly
Copy link
Contributor

PaulMaly commented Jun 9, 2019

@alex7kom Sure, please feel free to create appropriate issue in TS repo. Actually, this what I’m talking about. Everybody will get such kind of TS support in the same time when we’ll find the same page of TS site but only for HTMLx.

@alex7kom
Copy link

alex7kom commented Jun 9, 2019

@PaulMaly I'm sorry, I probably misunderstood you, it seemed to me you talked about TS in general rather than its nonexistent support of Svelte templates in particular. I'm not sure why the latter was needed to be pointed out in response for a link that says exactly that. 😕

@PaulMaly
Copy link
Contributor

PaulMaly commented Jun 9, 2019

@alex7kom To prevent any misunderstanding, I believe that current TS support in Svelte is enough to say we have it. We're able to write ts code with business logic in separate files .ts-files and import them using bundler setting. We're able to write ts code inside the component's logic using things like svelte-preprocess or svelte-ts-preprocess.

We could have even best support but unfortunately, Typescript itself is not supporting HTMLx for now. Perhaps when Svelte become more popular it'll be reasonable for TS support it. Until this, we can just try to make Svelte more popular with all passion.

@ShanonJackson
Copy link

ShanonJackson commented Jun 9, 2019

Its a chicken-and-egg scenario then because typescript wont support HTMLx until it becomes more popular but it can't be compelling to become popular for typescript users without first-class support.

Typescript team needs to make this happen.

@Rowno
Copy link

Rowno commented Jun 10, 2019

It looks like they'll be investigating plugin APIs for the TypeScript compiler for 3.6. That'll hopefully make it possible to add HTMLx support to TypeScript.

microsoft/TypeScript#31639

@geakstr
Copy link

geakstr commented Jun 22, 2019

I've prepared starter pack for personal usage. Maybe it'll be useful to someone https://github.com/geakstr/svelte-3-rollup-typescript-vscode

@pyoner
Copy link
Contributor

pyoner commented Jun 24, 2019

Hi guys!
Let me announce my work https://github.com/pyoner/svelte-typescript

Typescript monorepo for Svelte v3 includes

@quantuminformation
Copy link
Contributor

quantuminformation commented Jun 26, 2019

Number 200 thumbs up from me.

Coming from several TSX projects and 7 years of TS, I won't be going back to JS. Hope you can make head and tail of the TS API.

@mjgartendev
Copy link

Tagged template literals seem like the most feasible option, and probably the most technically correct, since it would just be a function that parses a string. Even something like each(ref, as, key)item template would be valid and match up with the handlebar syntax decently.

But I think the real issue at this point is that svelte markup syntax isn't well integrated with any kind of grammar spec. If we can describe it as WebIDL we could implement a language service that would provide much better editor support.

GraphQL is a good example of how powerful that can be. No matter how you write it or what environment you're in your tools always know exactly how to handle it.

@jeberly
Copy link

jeberly commented Jun 29, 2019

This is biggest thing holding us back from adoption of Svelte 3. We have tried the various plugin/workarounds mentioned above but keep hitting some quirks. We compared Svelte 3 to Stencil and we like Svelte better in every way except lack of TS support.

I don't mind playing whack-a-quirk with workarounds (or run w/o TS for awhile) if I know full TS support will be coming, but its hard to tell based on above comments what exactly is the current status.

I do also worry about the long term adoption of Svelte by the community with lack of out-of-box typescript support.

Edit:
I would be willing to pay a bounty for this if it would help. Or help in any other way if someone who understands the problem can split out tasks, or indicate how we can help move along upstream typescript changes that help facilitate this.

@Rolandisimo
Copy link

Typescript is definitely a selling point for me. I'm excited to see this project take over the world.

birtles added a commit to birchill/hikibiki-app that referenced this issue Jul 13, 2019
Rollup just isn't mature enough. In particular:

* It generates some cyclic dependency errors when importing chai
* The karma-rollup-preprocessor doesn't seem to map source file names
  propery (I worked around this locally by adding the following line to
  `createPreprocessor`):

```diff
          const { code, map } = result;
          const { sourcemap } = options.output;

          file.sourceMap = map;
+         file.path = map.file;

          const processed =
            sourcemap === "inline"
              ? code + `\n//# sourceMappingURL=${map.toUrl()}\n`
              : code;
```

* It has create trouble with fetch-mock. In particular it seems to need
  rollup-plugin-node-builtins (for query string) and then when it gets
  into the URL handling part of the code (using the WHATWG URL package)
  it somehow ends up in the node.js code path despite running in the
  browser which just means that everything breaks.

In the end it was just way too much work to fix all these bugs.

This patch switches us to Webpack which brings a new set of problems.
Namely that ts-loader doesn't know how to deal with svelte components.

Basically, at the time of writing (2019-07-13) Svelte's support for TS
is woeful. I'd love to use it but it's just not ready yet.

  sveltejs/svelte#1639
@jerriclynsjohn
Copy link

Is anyone working with Svelte using typescript in production, can you please let me know the hacks you've used to make it work. Can't wait to see the official support for typescript!

@carsoni
Copy link

carsoni commented Jul 24, 2019

I'm really enjoying the elegance of svelte but I would love to see official typescript support. It's just too hacky to try to get it to work at the moment and with mixed results even when it is working.

We have a substantial TS codebase written in support of a React UI but want to move to svelte as part of an architectural shift to the cloud.

Can't wait to marry our existing base to a new UI

@quantuminformation

This comment has been minimized.

@bobmoff

This comment has been minimized.

@sveltejs sveltejs locked and limited conversation to collaborators Jul 29, 2019
@Conduitry
Copy link
Member

We know this is important. More people saying that they can't wait for this - or how the lack of this is stopping them from using Svelte - is creating unnecessary notifications and isn't helping this happen any faster.

@Conduitry Conduitry added the meta label Sep 11, 2019
@pngwn
Copy link
Member

pngwn commented Oct 10, 2019

Some more discussion about a possible solution in: #3677.

@antony
Copy link
Member

antony commented Apr 9, 2020

Closing in favour of #4518

@antony antony closed this as completed Apr 9, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests