-
-
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
svelte-kit package: Generate type definitions #1646
Conversation
Apart from a little cleanup and the One question that is left for me is: Do we want to add types by default? - which would mean the user has to install TypeScript and svelte2tsx even in JS-only projects. I'd probably say "yes" to force package authors to be a good citizen of the ecosystem and to provide types. |
Absolutely, and yes to force authors to be a good citizen of the ecosystem. Svelte components exported from a js file without types is (at least) usable but not the best experience for regular users, and virtually unusable for TS users. Importing the svelte files itself is a workaround, but with exports map, the imports are essentially locked so no importing source files directly. Should they install TypeScript and svelte2tsx themselves? Can't we automatically install or add it for them when they run |
reason: right now language tools see a Svelte file and will always pick that one, even if there are types defined for that file somewhere else (the "types" folder). If a svelte.d.ts file is next to a svelte file however, the d.ts file is picked up instead. This default ensures that deep imports will also work as expected (picking up the type definition)
I'm not sure we can because people could be using npm, yarn, pnpm, or whatever to do this, and I'm not sure there's a good way to detect this. This is now ready for review (with a pending answer to the svelte2tsx/typescript question), I'll add a changeset soon. |
That's true. Also, some docs update would be nice. |
the types folder defines where to put the types, the entry is for the "types" field of the package json
🦋 Changeset detectedLatest commit: 22c57ca 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 |
I split up the types option into one for the folder and one for the entry point, because they not necessarely have to correlate with each other. I also added some docs and a changeset, so this should be good to merge if there are no objections to the way types are forced by default and the requirement to instal typescript/svelte2tsx by hand. |
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.
Looking good, can't wait for this to be merged!
Co-authored-by: Ignatius Bagus <ignatius.mbs@gmail.com>
restructure new content a little
Curious if |
@dummdidumm it looks like this one will need a rebase |
Jsdoc->dts should work now, too. I'll try adding a test later for all of this. Regarding the overwrite: I was about to write "To me this feels like something that is the user's fault and they need to structure the exports differently", but then I thought "how do I even do that without TypeScript files, if I only use JS and dts files?", so that's a good question. The only thing that comes to my mind is to append the manual d.ts file content to the generated one. Or the user is expected to write a little bit of duplicated code by doing export { default as Circle } from './Circle.svelte';
export { default as Square } from './Square.svelte'; index.d.ts export { default as Circle } from './Circle.svelte';
export { default as Square } from './Square.svelte';
export type Point = {
x: number;
y: number;
}; |
Added tests, which uncovered some more subtle bugs, and added a warning if a generated d.ts file is overwritten by a handwritten file. @Rich-Harris I think in this case its best to place the burden on the author to enhance his d.ts file and have a little duplication. The alternative of automatically appending the handwritten content to the generated one might not always be what you want. This is now ready to merge, although it would be great if you could test this out on your own package before merging it @Rich-Harris . |
I tried this out on an unreleased library and it worked great once I figured out that I needed to replace my But when I used the library with the freshly generated types, I started seeing errors like this: The <script>
import * as THREE from 'three';
import { setup } from '../../utils/context.js';
import { transform } from '../../utils/object.js';
import * as defaults from '../../utils/defaults.js';
export let position = defaults.position;
export let rotation = defaults.rotation;
export let scale = defaults.scale;
export let renderOrder = 0;
const { root, self } = setup(new THREE.Group());
$: {
self.renderOrder = renderOrder;
transform(self, position, rotation, scale);
root.invalidate();
}
</script>
<slot></slot> The generated declaration looks like this: /** @typedef {typeof __propDef.props} GroupProps */
/** @typedef {typeof __propDef.events} GroupEvents */
/** @typedef {typeof __propDef.slots} GroupSlots */
export default class Group {
}
export type GroupProps = typeof __propDef.props;
export type GroupEvents = typeof __propDef.events;
export type GroupSlots = typeof __propDef.slots;
declare const __propDef: {
props: {
position?: any;
rotation?: any;
scale?: any;
renderOrder?: number;
};
events: {
[evt: string]: CustomEvent<any>;
};
slots: {
default: {};
};
};
export {}; I'm not sure what the relationship between |
Found the reason why this wasn't working for jsconfig files and in your case for the tsconfig. Turns out we need to force some more TS config options. Tested this on your project and it works now as expected. Merging as this feels battle-tested enough now. |
Even if emitting types is the default, there should definitely be an option to disable them. How about |
Could you elaborate why this should be configurable? I see no harm in always generating types as long as they are sound. |
Because of the added dependencies on |
You only need those when authoring packages, for which I think it is best for the ecosystem quality to generate types, always. Or do you see use cases where this would be bad? |
I'm all for types! There's no use case where I think they would be bad except maybe people building packages only for personal use who don't want to deal with types. But I think the incentive to add types is strong enough if you enable them by default. There should still be an escape hatch for unforeseen scenarios. When documenting such a new option, you could simply include your statement
or something along those lines. |
Sounds good. If you want to create the PR, this commit can serve as inspiration where to make the changes for the option. Also a test would be nice. |
WIP
Closes #1628
Fixes #1717
TODO
generate only the files from within the lib folder, not others. Not sure how to best accomplish this. Either postprocess and remove all definition files from other places, or manipulate the tsconfig prior to the emit in a way that it only traverses the files inside the lib folderaddtypes
to the generatedpackage.json
Move some postprocessing of the generated tsx into svelte2tsxOpen questions:
svelte2tsx
become a dependency, a peer dependency, or nothing of that? It's needed to generate the type definitions