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

Working TS compiler & AST type checker #3677

Closed
marcus-sa opened this issue Oct 9, 2019 · 54 comments
Closed

Working TS compiler & AST type checker #3677

marcus-sa opened this issue Oct 9, 2019 · 54 comments

Comments

@marcus-sa
Copy link

marcus-sa commented Oct 9, 2019

I've seen multiple requests for TypeScript support.

This can be done in a few ways:

  1. Using the TS compiler API directly in the Svelte compiler for transforming scripts into components and then do type checking support against the template AST.
  2. Writing a compiler specifically for TS on top of the Svelte compiler with integration for Rollup, Webpack & Bazel.

The second approach is something I've taken a shot at, quite successfully I must say.

The compiler transpiles all scripts into valid JS that the Svelte compiler can transform into components and then it creates declaration files for the components, that the type checking then can consume later on to validate the components and templates.
It saves the AST compilation in a cache which then later on, the TS type checker is used to validate everything.

What's your opinion on this?

The repository can be found at https://github.com/marcus-sa/svelte-ts

@swyxio
Copy link
Contributor

swyxio commented Oct 9, 2019

related sveltejs/sapper#760 and #1639

@pngwn
Copy link
Member

pngwn commented Oct 9, 2019

Yep, there is already an issue about this.

@pngwn pngwn closed this as completed Oct 9, 2019
@marcus-sa
Copy link
Author

marcus-sa commented Oct 9, 2019

Not really the same issue.
That issue only describes transpiling TypeScript in scripts, but not type checking or generation of component declarations.

Yeah, what you just linked to is such a small part of actually implementing TS support..

@marcus-sa
Copy link
Author

marcus-sa commented Oct 10, 2019

So it really sounds like you guys don't care about TS support at ALL.
You decide to close a thread which identifies and tries to solve the issue, so that everyone can be happy with the tooling usage of Svelte.

Once you saw the title being named something with "TypeScript" you probably just closed it immediately.
It's understandable because people keep asking about it, but if you gave some answers then people wouldn't.

Should I continue this project to support TS fully, or are you planning to extend your compiler & checker with TS capabilities?
Just want to know whether or not I'm wasting my time.

@pngwn
Copy link
Member

pngwn commented Oct 10, 2019

I didn't link any issues. I should have linked to the relevant issue and I apologise for that. The issue I was referring to is this: #1639

I closed it because we already have an issue to discuss TypeScript support. Comments relating to TS support in Svelte components, what it should cover and how it could or should be implemented, should be directed the existing issue.

We always close duplicate issues to reduce noise in the repository, having several issues for each feature request is not going to make dealing with them easier, however noteworthy the author thinks their issue is.

Regarding Typescript, people do ask about it frequently and we, almost as frequently, respond that there is an issue to track it, we haven't got around to it yet and when we have any updates we will share them. If someone else wants to take this on, we welcome contributions from the community.

@quantuminformation
Copy link
Contributor

As a TS dev since 2012, I actually don't care about TS support given how much JS tooling has improved.

https://www.youtube.com/watch?v=xHI8S4gRQYg&t=4s

@marcus-sa
Copy link
Author

marcus-sa commented Oct 10, 2019

@quantuminformation that's why I'm asking whether or not they're going to support it, or if I should continue on my own.
For me it doesn't really matter, I just want some clarification.

I only gotta take some precautions on whether or not the html AST is going to include breaking changes in the future.

@marcus-sa
Copy link
Author

@pngwn cheers. I guess I'll continue my project then 😄
The issue you linked to is locked btw.

@quantuminformation
Copy link
Contributor

quantuminformation commented Oct 10, 2019 via email

@pngwn
Copy link
Member

pngwn commented Oct 10, 2019

I did not realise that. I'll reopen this issue so further discussion on this solution can take place.

This isn't an invitation for everyone to ask 'is it ready yet', so let's keep things focused on the solution at hand.

There is definitely a desire for first-class typescript support, we don't necessarily have strong opinions on how that would work right now. As you can see from this comment this is something we want to do. But as you can also see from this comment we havent gotten around to it. Nothing has changed materially since the last comments in that issue were made.

@pngwn pngwn reopened this Oct 10, 2019
@pngwn pngwn mentioned this issue Oct 10, 2019
3 tasks
@mindplay-dk
Copy link

  1. Writing a compiler specifically for TS on top of the Svelte compiler with integration for Rollup, Webpack & Bazel.

Bazel 🤔 ... did you mean Babel?

@marcus-sa
Copy link
Author

marcus-sa commented Oct 11, 2019

@mindplay-dk no I meant Bazel :)
The implementation was specifically made for Bazel, but the compiler and type checker will be decoupled so that they can be used for Webpack & Rollup as well.

https://asciinema.org/a/273603 👀

@sisou
Copy link

sisou commented Oct 11, 2019

This is awesome! 👍 It even tracks child component props usage in the parent, something I am always missing!

This issue should probably be renamed to something like "Working Typescript Compiler" to show that you are actually suggesting a solution, instead of just asking for TS plans.

Can you explain a bit simpler of how your solution works? As I understand, first you compile the scripts and templates with TS while caching their AST and generating declaration files per component, then let Svelte compile the components, and then do the actual type-checking on the compiled JS?

@marcus-sa
Copy link
Author

marcus-sa commented Oct 11, 2019

@siosu I'll try to create a more descriptive diagram over the process (it's complex), but yes, you're close.
It type checks against the generated component declarations.

Compiler:

  1. The compiler reads all the source files
  2. Everything except the content of the script tags gets thrown away
  3. The script source code gets compiled to valid JS and declaration files.
  4. Jumps back to step 2, where it replaces the TS source in script tags with the compiled JS
  5. The Svelte compiler compiles the entire source file
  6. The output compilation of above step gets cached, where the HTML AST is then used in the type checker.

It consumes the exported variables and functions from inside a Svelte script, and then generates it as a declaration files which contains a class that extends the runtime SvelteComponent.

Typechecker:

  1. The type checker finds all components in the cached AST.
  2. Checks all components in the template is a valid class which extends SvelteComponent
  3. Checks for valid declarations, properties etc.

This means that if you're using a 3rd party library that offers Svelte templates, they should either:
a) Write declaration files by hand.
b) Compile the library using this project.

Alert.svelte.d.ts

import { SvelteComponent } from 'svelte/internal';
export default class Alert extends SvelteComponent {
  type: 'success' | 'info' | 'warning' | 'error';
}

@marcus-sa marcus-sa changed the title TypeScript plans Working TS compiler & AST type checker Oct 11, 2019
@miguelsan
Copy link

For a Typescript preprocessor, see https://github.com/kaisermann/svelte-preprocess#typescript.

@marcus-sa
Copy link
Author

marcus-sa commented Oct 16, 2019

@miguelsan not the same and is pretty irrelevant to the thread, as I assume most people know that there's already 5-6 TS preprocessors for Svelte.

@VictorGaiva
Copy link

VictorGaiva commented Oct 27, 2019

EDIT: Ignore what I say here. I got corrected bellow.

My take on this is that it we shouldn't be working on this support from the Svelte side. The same way the JSX Syntax is supported by Typescript compiler, Svelte should be too.

  • It uses some syntax sugar we don't see elsewhere, like JSX.
  • It is basically valid Javascript with some twists, like JSX.

Babel, as a compiler, supports JSX, at compile time with the addition of a preset. When we are using type-checking, it still uses tsc itself, which is the thing we care the most about. I believe that the Svelte compiler should care about only its own syntax. Since the project is still growing, we have a limited amount of resources to be spending on native Typescript support.

A good point was made on this comment on Typescript's issue tracking.

Typescript should support Svelte

@marcus-sa
Copy link
Author

marcus-sa commented Oct 28, 2019

@VictorGaiva have you even read the thread you're commenting on?
Svelte will never be natively supported by the TS compiler, are you crazy? Not even Vue or Angular is (and for a good reason)
React is completely compiler independent; Vue, Angular and Svelte aren't.
I think you should research as to why JSX was actually implemented in TSC, before you make such an obnoxious statement.
JSX is syntactic sugar which compiles down to JS.
JSX is used in various different frameworks such as React, Preact, Stencil, Inferno and so on.
Every other framework has their own lexer, parser and compiler.

@VictorGaiva
Copy link

@marcus-sa , thank you for the explanation.

@miguelsan
Copy link

@miguelsan not the same and is pretty irrelevant to the thread, as I assume most people know that there's already 5-6 TS preprocessors for Svelte.

It would be nice it you could highlight the main difference between those preprocessors and this "TypeScript support": I find it hard to understand the purpose of this, since you only describe the how, and it even takes time to follow you on that.

@arnold-graf
Copy link

arnold-graf commented Oct 30, 2019

@miguelsan This project aims to check types on expressions in the template and across component boundaries as opposed to other somewhat popular projects that only check types within the <script> tag of a single .svelte component. That makes it a lot more useful to many people.

@beenotung
Copy link

from the video demo in the readme of svelte-ts, it seems working already, what else are missing? want to help on this

@acutmore
Copy link

acutmore commented Nov 3, 2019

For those asking why this approach is needed. Here is an example of the Type-Errors that this approach would catch, over the script tag preprocessor-only approach:

// Inner.svelte

<script lang="ts">
  export let names: string[];
</script>

<ul>
  {#each names as name}
    <li>{name}</li>
  {/each}
</ul>
// Outer.svelte

<script lang="ts">
  import Inner from './Inner.svelte';
</script>

<Inner names="Alice,Bob" />  // Error! type 'string' is not compatible with type 'string[]'

@carbotaniuman
Copy link

Typescript support is blocking me from using Svelte, so this is appreciated!

@Gorthog
Copy link

Gorthog commented Nov 24, 2019

This is exactly what I'm looking for!
Can any of Svelte guys comment on whether or not they approve of this approach? What will it take to fully embrace it? I would love to contribute, but only if this is going to be incorporated into Svelte itself.

@btakita
Copy link
Contributor

btakita commented Nov 30, 2019

I propose having Svelte support the src attribute on the script tag. #4026

If such an api were adopted with Svelte, the following would apply.

In the case of svelte-ts, the compiler can implicitly create MyComponent.ts from the typescript contents of the <script> tag. This way, the Svelte library has an explicit contract on handling other languages such as typescript, livescript, coffeescript, etc. while using the standard cli tools for these libraries & not having to resort to preprocessors.

@marcus-sa
Copy link
Author

marcus-sa commented Dec 3, 2019

@halfnelson that's pretty cool, but isn't it quite slow?

@halfnelson
Copy link
Contributor

halfnelson commented Dec 3, 2019

svelte2tsx is pretty fast, typescript is slow yes :) which is why it is left as a stand-alone-tool here. It checks the svelte site src folder in about 3sec,

Processed 175 files:
  Found 9 errors

@arnold-graf
Copy link

echoing @sinapis question, would the svelte team consider adopting either @marcus-sa’s or @halfnelson’s approaches? If not, what would be a feasible approach to perform the same checks and get this sort of "complete" type safety? happy to contribute! cheers

@rendall
Copy link

rendall commented Jan 2, 2020

I'm new here, so forgive me if I'm rehashing something obvious. I'm wondering if this approach would be worth pursuing, or if it has been done. For the case of Svelte components imported into .ts files, would it be a good approach for a preprocessor to generate type definition (.d.ts) files from .svelte files?

That is to say, this code in a .ts file

import App from './App.svelte';

const app = new App({
	target: document.body,
	props: {
		name: 'world'
	}
});

... would trigger the generation of this App.svelte.d.ts file:

declare class App {
  constructor(o:{target:HTMLElement, props:{[name: string]:any}});
}

export default App;

Personally speaking, this would be a "good-enough" for me, at least until there is first-class support. The typescript compiler could compile this into javascript as an intermediate step, and the normal svelte compiler could take it from there.

What am I missing?

@jerrygreen
Copy link

@fredrik-macrobond a lot of people do, don't overwhelm everyone by spamming messages. To express yourself please use this:

image

If you want to subscribe to the topic updates, please use this:

image

If you have some meaningful information regarding the topic or want to help (frustrating everyone with meaningless notifications isn't helping), then welcome to the messages :)

@mistlog
Copy link

mistlog commented Jan 30, 2020

Hi, maybe there is another approach to support typescript.

Due to the compiler nature of svelte, we can treat any svelte file, i.e. *.svelte as compilation target, and then write code in typescript and compile each *.tsx to *.svelte.

The problem is that currently we have to use tool such as webpack or preprocessor to wrestle with both template and script. What we want is COMPLETE support for typescript, and only TOOLS can't acheive this goal perfectly.

Thus it seems appealing to solve this problem in LANGUAGE level. Recently, I implemented typedraft, which is a superset of typescript with built-in support for code transformation, and it's relatively easier to do translation in this new language.

The solution is repo svelte-draft, a single CLI tool, *.tsx in and *.svelte out. Also, I find that it's possible to get complete support for typescript in this way, and it 's just a matter of time. There are some samples:

Here is the analogy for this approach:

  • binary -> x86 assembly -> C/C++/Java/C# ...
  • html, js, css -> svelte -> svelte-draft

@mistlog
Copy link

mistlog commented Feb 13, 2020

I have rewritten almost all examples in https://svelte.dev/tutorial with full power of typescript in this new approach.

Repo: https://github.com/mistlog/svelte-draft-tutorial.

@marcus-sa
Copy link
Author

marcus-sa commented Feb 13, 2020

@mistlog sorry to say, but that's not using svelte templates...
The entire idea of this implementation was to use Svelte as it is with full TypeScript support and not some custom JSX like you've done, otherwise it'd make more sense to use Stencil than Svelte if comparing to your approach.
Nice project nonetheless.

@mikecann
Copy link

I have rewritten almost all examples in https://svelte.dev/tutorial with full power of typescript in this new approach.

Repo: https://github.com/mistlog/svelte-draft-tutorial.

Wow nice work! Works really well!

I tried a whole bunch of the examples and it all works well. Example 14 / Slot Props doesnt compile tho for some reason.

@mistlog
Copy link

mistlog commented Feb 13, 2020

@mistlog sorry to say, but that's not using svelte templates...
The entire idea of this implementation was to use Svelte as it is with full TypeScript support and not some custom JSX like you've done, otherwise it'd make more sense to use Stencil than Svelte if comparing to your approach.
Nice project nonetheless.

Thanks for your comment!

@mistlog
Copy link

mistlog commented Feb 13, 2020

I have rewritten almost all examples in https://svelte.dev/tutorial with full power of typescript in this new approach.
Repo: https://github.com/mistlog/svelte-draft-tutorial.

Wow nice work! Works really well!

I tried a whole bunch of the examples and it all works well. Example 14 / Slot Props doesnt compile tho for some reason.

I'm sorry and it's related to mistlog/svelte-draft-template#3.
Run npm run dev again and it works.

@jerrygreen
Copy link

jerrygreen commented Feb 13, 2020

Yea, one of my main concerns about Svelte, - it's overloaded with some template code out of the box. It was mentioned many times that Svelte is inspired by NextJS many times. Though, if you'll create NextJS project:

npx create-next-app

You'll get a fine structured folder, with a few code dependencies in package.json, with just 2 example pages [you'll later replace], and no any configs at all.

Though, if you'll want to create a Svelte project...

npx degit sveltejs/template my-svelte-project

I could already notice "what is this degit?", and why can't I use just npx create-svelte-app? But it's not my real concern here...

And what do I get in a newly created project? Yes, a similar example page, which I will replace with my real page, but what else?.. Rollup config? Some main.js? And also... A README.md with a hundred lines, which also asks me to run npx degit sveltejs/template svelte-app, srsly?

And, for the sake of justice, I admit, - it's already much better than it was months (a year?) ago. Earlier, there was also a service-worker.js... Btw, I hope it's not just "removed" now, but encapsulated somewhere?

For typescript support you'll also need tsconfig.json, - which is okay (ideally, to extend it from the library???), but if it will also require some additional configs like some another more complex rollup config, some library types within a project, etc., - then it will make the "no config" situation even worse. If I create a new project, and it's overloaded with tons of configs right from the start, - it's only part of the issue that your mind is overloaded too, but another issue, - you won't get updates regarding changes to these configs. I.e. if there will be some changes in svelte, for initial rollup config, tsconfig, etc., - then, because they are part of the project, not a part of the library itself, you will have to change them manually upon library updating.

Best practices, anyone?

So in our programming world we have this good practice of having no configs required. A good practice of having default values. A good practice of conventions over configurations. A good practice of encapsulations. And by breaking these laws, it brings a lot of frustration when one uses such instruments.

And I suppose it's very important thing here in this issue, "no configs", - that what it means "to have first-class typescript support". Otherwise it's not first class, - maybe some economy class, having you to say: "yes, we support typescript but...".

Yet, don't get me wrong, - a lot of guys here did real good work toward typescript support here. This TS-based compiler, and this tutorial rewrite... I really appreciate your guys work, and willingness to use typescript, - I like typescript too! I just point to important problems I see with these typescript template repositories some of you share here. I understand "then do it yourself" concept, I'm just not ready to. Currently, pointing to where's the problem is much easier for me than implementing a solution here, - it's real hard, and that's why I so much appreciate your guys work here! I hope, I helped someone to see things a bit clearer. Thx for attention :)

@davidroeca
Copy link

davidroeca commented Feb 13, 2020

So I’ve been watching this issue and look forward to native typescript support if that’s possible (or an officially endorsed plugin that supports typescript).

One thing that struck me as odd here was the discussion of “best practices”. While best practices help teams stay consistent, blindly picking “best practices” will lead to unnecessary religious debates that boil down to opinion, legacy, and laziness rather than what’s actually “best”. Best practices in one context can be horrible practices in another context.

Let’s table “best practice” debates until we settle on the right solution that balances the needs of the svelte team and the needs of users.

Edit: One need would be simplified configuration. The trade-off here is that the "simpler" the configuration is, the harder it is for users to control, and the more complex it is for power users to update. Think of something like create-react-app which is really easy to get started with but has been historically challenging and implementation-specific to tweak to your own needs.

@mikebeaton
Copy link

mikebeaton commented Feb 14, 2020

@marcus-sa,

Based on your videos and description (I haven't tried it yet) you've got working TS for Svelte. As we know, TS makes it far easier to stay on top of changes once it comes to refactoring, even though it's a bit slower to write in the first place, which is why a lot of people would want it before migrating (or starting) business critical code on Svelte. And we already know that @Rich-Harris wants TS in Svelte.

But your PR hasn't attracted a single comment from a core team member! Though - of course - the comments you have got from some of the authorised project collaborators are very welcome.

So... I've previously made the mistake of dropping a big update - which I really did and do think added something useful (and some agreed with me!) - onto an open source project without discussing it thoroughly first... and I agree, yours really is a useful update! But my experience is that (unfortunately, when the update in question really is useful to project users) this either gets ignored or ruffles feathers; and fairly so, in hindsight.

In this case, there's already work afoot to integrate TypeScript #1639, so I'm sure they'd want to understand: is your work compatible with what's been done so far? And probably even more crucially, can it achieve whatever goals the team has already decided are most important for TS in Svelte to achieve?

I wonder if there's any way you could try to establish direct contact with the team to discuss this?

There's the Discord chatroom, but perhaps another approach would be to try a short, polite, public PM on this channel, very politely and modestly pointing out that you have working cross-component Typescript in Svelte, linking to your two videos (which kind of prove the point!), and asking whether Rich would be interested in discussing it more over PM, and potentially working together? (It sounds like you're definitely prepared to put the time in, over the long term, if the team want to work with you - which is obviously good!)

(One other obvious question, how far can you go with integrating your work into as close as possible to the standard Svelte build chain?)

m8, thanks, it looks very cool! Good luck!

Mike

@AlgoTrader
Copy link

AlgoTrader commented Feb 23, 2020

I have analyzed Svelte commits for last half a year. Please correct me if I am wrong, but there is no a single commit related to Typescript support. There is no slightest sign of any progress in the area. I would like to choose Svelte for a project, but I cannot argue it is the right choice. I would like to know if Svelte team has any roadmap and vision of implementing TS. I also want to know whether they just do care. Just tell us when there will be any progress in the direction

PS. They don't care

@Aeolun
Copy link

Aeolun commented Feb 25, 2020

@AlgoTrader I would personally assume the team just has different priorities.

Is there any chance of using this as a wrapper around whatever version of Svelte? In that case the work on both could proceed independently.

@alpham8
Copy link

alpham8 commented Mar 4, 2020

Guys, does simple TypeScript to JavaScript compiling and then triggering the svelte compiler work?

@mikebeaton
Copy link

mikebeaton commented Mar 4, 2020

@alpham8 Yes, if you don't want type-checking between components; but you almost certainly do, and it's not enough if you do.

@orta
Copy link
Contributor

orta commented Mar 6, 2020

Hi folks, I've chatted with Rich a bunch about TS + JS with Svelte and came up with a proposal which lets people add TS to Svelte apps, and for folks to start building upon the existing tooling infrastructure to provide a rich editor experience.

#4518

This lets the current svelte contributors continue to work on the compiler while opening up the chance for more people to start working on centralized tooling to improve editor experience (which includes TS support)

If you've commented in here, you might be the sort of person who can help make it happen 👍

@the-homeless-god
Copy link

https://github.com/Zimtir/ST-template

@yahorsi
Copy link

yahorsi commented Apr 1, 2020

SPOILER: 999% that below is something very stupid

Has anyone already suggested to NOT adding TS support and instead implement JS->JS transpiler?
Like TS compiles to JS, and then Svelte could analyze JS assignments and do its magic?

@alpham8
Copy link

alpham8 commented Apr 7, 2020

SPOILER: 999% that below is something very stupid

Has anyone already suggested to NOT adding TS support and instead implement JS->JS transpiler?
Like TS compiles to JS, and then Svelte could analyze JS assignments and do its magic?

The folks want TypeScript, no matter if you like it or not...

@mikebeaton
Copy link

Has anyone already suggested to NOT adding TS support and instead implement TS->JS transpiler?
Like TS compiles to JS, and then Svelte could analyze JS assignments and do its magic?

@yahorsi Yes, 4 comments above yours in this issue, and several other places further above, and elsewhere in linked issues.

@rendall
Copy link

rendall commented Apr 7, 2020

SPOILER: 999% that below is something very stupid
Has anyone already suggested to NOT adding TS support and instead implement JS->JS transpiler?
Like TS compiles to JS, and then Svelte could analyze JS assignments and do its magic?

The folks want TypeScript, no matter if you like it or not...

This reads harshly. I believe "JS->JS" was a typo and poster meant to write "TS->JS"

@beenotung
Copy link

beenotung commented Apr 7, 2020

This maybe side tracking, but want to share to the peers.

If you're looking for TS/TSX with svelte, I suppose you're looking for a 'no-vdom' reactive programming experience with TSX. In this case, surplus[1] maybe what you're looking for. I just tried out it recently and like it a lot.

[1] https://github.com/adamhaile/surplus

@alpham8
Copy link

alpham8 commented Apr 7, 2020

SPOILER: 999% that below is something very stupid
Has anyone already suggested to NOT adding TS support and instead implement JS->JS transpiler?
Like TS compiles to JS, and then Svelte could analyze JS assignments and do its magic?

The folks want TypeScript, no matter if you like it or not...

This reads harshly. I believe "JS->JS" was a typo and poster meant to write "TS->JS"

Oh, my bad, I'm terribly sorry. I didn't wanna be nasty. Just keep friendly and polite and stick together for the coding goal here 😄 👍

@antony
Copy link
Member

antony commented Apr 11, 2020

In progress via #4518

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

No branches or pull requests