-
-
Notifications
You must be signed in to change notification settings - Fork 2k
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
App-level types #3569
Comments
I found a working solution which might be even more idiomatic than the namespace approach:
type WithAnyFallback<T> = T extends never ? any : T; Edit: Turns out we don't even need this, TS falls back to declare module '$app/stores' {
// ..
// @ts-ignore
export let session: Writable<Session>; // pre-edit: Writable<WithAnyFallback<Session>>
}
declare module '$app/stores' {
export interface Session {
whatever: 'i want';
}
} TypeScript will merge the module declarations, which means So the way forward would be to
|
I'd argue that the namespace is more idiomatic. It so happens that Separately, I think |
* add a SvelteKit namespace for app-level types (#3569) * update templates * update docs * fix some test types * get typechecking to pass * document app-level types * changeset * link to typescript section * rename namespace to App * update changeset * shut up eslint no-one likes you * point to docs * remove Locals from todos/_api default template * update adapter-cloudflare docs Co-authored-by: Ignatius Bagus <ignatius.mbs@gmail.com>
This is how typescript works. The d.ts file stops being an ambient module file as soon as you add a top level export or import, so they stop adding these types to the global types. So you should avoid doing that. Maybe we should add a comment in the starter template making this more clear. This also was why I preferred "global" as a file name. |
So then how do I reference a type that isn't in the same file? |
For reusable types you want to import, create a separate d.ts file. |
you can |
Importing inside the namespace works! Thank you. |
Ah. Import inside a namespace isn't right. That only works inside the |
I'm having issues with the type importing thing as well. /// <reference types="@sveltejs/kit" />
declare namespace App {
interface Session extends import('ts-essentials').DeepWritable<import('./someFile').BasicSessionInfo> {
isAuthenticated: boolean;
}
} But it's not working, do generics fail to work when using dynamic imports like this?! Or am I doing something wrong? |
Describe the problem
Various types in a Kit app are app-level, by which I mean they're the same wherever they're used —
event.locals
,event.platform
,session
, and arguablystuff
(which, even though it's scoped toload
, can be used globally as$page.stuff
and is therefore probably best thought of and used as a consistently-shaped object, where inputstuff
and outputstuff
inload
are bothPartial<Stuff>
).It's wasteful, therefore, that to take full advantage of type safety it's necessary to use generic arguments everywhere:
It's also a problem that
RequestHandler
andHandle
take positional generic arguments — it meant that the addition ofPlatform
was a breaking change, for example. And why doesn'tRequestHandler
acceptparams
? If we fixed that, it would be another breaking change.With app-level types (and assuming we were to treat
stuff
as app-level), the examples above could be rewritten thusly:Stretch goal — no manual typing at all
A priori, it's silly that you have to type
params
— SvelteKit already has that information. It should make it available... somehow.In an ideal world, it wouldn't be necessary to type
props
either — that would be inferred from the props in the<script>
block.In an even idealer world, TypeScript would support implicit module typing and you wouldn't even have to declare types.
I've no idea how feasible any of this is in the real world (maybe there's something sneaky/clever we could do with
preprocess
?) but this is the development experience we should be aiming for, even if we fall short.Describe the proposed solution
I'm not much of a TypeScript expert, so I don't really know how we would do this. @dummdidumm had a suggestion:
Alternatives considered
No response
Importance
would make my life easier
Additional Information
No response
The text was updated successfully, but these errors were encountered: