-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
feat: native TypeScript support #9482
Conversation
🦋 Changeset detectedLatest commit: 46d4073 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
The latest updates on your projects. Learn more about Vercel for Git ↗︎
|
No idea why there's a lint issue, can't reproduce locally |
If it's a compiler thing with this change, would it make sense to have it as a compiler option so People that use TS could then just turn that on in the config to have TS everywhere and in special cases where it should be off, |
Some thoughts:
|
Hi! Hopefully I understood correctly,
should this be disallowed or supported/tested? |
This is great! We could even add TypeScript to this whole repository - what does everyone think? |
It will! We just need to do some hoop-jumping to differentiate between the different types of |
An application-wide |
Per discussion elsewhere, we now only parse in TypeScript mode if there's a |
@@ -10,6 +10,7 @@ | |||
"noErrorTruncation": true, | |||
"allowSyntheticDefaultImports": true, | |||
"verbatimModuleSyntax": true, | |||
"skipLibCheck": true, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we need this? We should avoid setting this, as it's going to hide any type errors we introduce inside d.ts
files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
because of type checking errors that were happening inside acorn-typescript
. i'm not sure if there's a way to disable checks for a specific library? if not then to remove this we would need to fork acorn-typescript
or work with the maintainers (hi @ota-meshi!) to figure out those errors. That would be preferable of course, I just didn't include that work here because it was initially more of a PoC than anything
If we were to remove it, vite import scanner would need a new way to determine if a .svelte file script has typescript in it too. Right now it does look for lang="ts" for a few sfc extensions on it's own (.vue and .svelte at least) |
hmm, i think in that case we'll have to somehow tell vite that we emit ts and not js (does that work with a faux .ts extension in resolve?). It could work but what about other bundlers that dont have vites pre/post ordering? not sure it would work with rps and no clue at all about svelte-loader or others. What would be the reason to not emit plain js? |
There are two possibilities — reading from export default {
compilerOptions: {
typescript: true
}
}; ...or reading from {
"svelte": {
"typescript": true
}
} The first feels nicer, but creates problems because the TypeScript plugin also needs this information, and it has to work synchronously. That's easy with
We do emit plain JS |
Except that now you need a pile of hacks to read it from tsconfig. I'd recommend tsconfck for this but it's async. Native ts utilities are orders of magnitude slower. I also don't think that vite would implement a different scheme than In the long term, i believe a project config for this should be in svelte.config.js, not only because it's nicer but because it is svelte config, not typescript config. A more generic way of doing this would be to use frontmatter (in svelte.config.js AND .svelte files) to have sync parsable compiler options on a global/file basis. This could replace svelte:options aswell. last but not least if you really want to put it into a json file for sync parsing, i'd prefer using package.json over tsconfig.json. This is a lot easier to find and parse.
great, so just to confirm, this addresses the point from @dummdidumm above confirming that the compiler strips types or is there another js->js transform needed to remove something? If yes, I think it should be done by the compiler to avoid it having to be implemented in different places. |
Before going ahead I'd like to make sure this works with language tools and the prettier plugin |
just curious, but how come these acorn plugins are still working with rollup 4? seemed like rollup 4 all about sunsetting acorn |
We don't use acorn through rollup, we import it in the compiler and our files go through the |
Since Svelte loves putting logic in file names, here another suggestion: Naming files *.js.svelte or *.ts.svelte to specify the language. |
Thought I'd have a quick look to see how feasible it would be to support TypeScript natively via acorn-typescript. Props to @gtm-nayan for the initial prototype, which this leans on heavily.
Turns out it's quite reasonable, at least to the extent that I've tested it. Notes:
ts-expect-error
annotations on it to get rid of the red squiggliesloc.start.index
andloc.end.index
) that we need to delete. It also seems to forget to setend
on a node when it has a type annotation. Not sure why. Both workaroundableeach
blocks might be tricky, becauseas
in{#each things as thing}
looks like a type assertion, and thus part of the first expression. Turns out we can solve that in most cases quite simply, just by unwrapping the assertion and rewinding the parser to before theas
{#each x as { y = z }}
, becausex as { y = x }
won't parse. MostPattern
nodes can happily masquerade asExpression
nodes, butAssignmentPattern
nodes cannot. In these cases we employ a dreadful hack: we look for the most recent occurrence ofas
, blank out everything from there onwards, and try parsing the expression again. We keep doing that until we get a valid expression. This is absolutely horrific but it seems to workparseExpressionAt
to read the snippet parameter (because of thePattern
thing, again), we have to read the parameter using our existing pile of hacks, then construct some artificial code to coax Acorn into giving us the type annotation, if such there beTSAsExpression
andTSNonNullExpression
nodes at transform time), and could potentially provide some future value<script lang="ts">
. Truthfully, I'm not sure what we should do here.lang="ts"
is a convenient place to put the setting, though it's also slightly weird if it also controls how the template is parsed. (What if<script context="module">
disagrees with<script>
?)lang="ts"
, then would we no longer need the preprocessor?Svelte 5 rewrite
Please note that the Svelte codebase is currently being rewritten for Svelte 5. Changes should target Svelte 5, which lives on the default branch (
main
).If your PR concerns Svelte 4 (including updates to svelte.dev.docs), please ensure the base branch is
svelte-4
and notmain
.Before submitting the PR, please make sure you do the following
feat:
,fix:
,chore:
, ordocs:
.Tests and linting
pnpm test
and lint the project withpnpm lint