Adjust way of adding types to output, add more convenience types

Closes #7584
pull/6770/head
Simon 4 years ago
parent 995c509708
commit a8e616be78

14
package-lock.json generated

@ -44,7 +44,7 @@
"sourcemap-codec": "^1.4.8", "sourcemap-codec": "^1.4.8",
"tiny-glob": "^0.2.6", "tiny-glob": "^0.2.6",
"tslib": "^2.0.3", "tslib": "^2.0.3",
"typescript": "~4.0.0" "typescript": "^3.7.5"
}, },
"engines": { "engines": {
"node": ">= 8" "node": ">= 8"
@ -4402,9 +4402,9 @@
"dev": true "dev": true
}, },
"node_modules/typescript": { "node_modules/typescript": {
"version": "4.0.8", "version": "3.9.10",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.8.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz",
"integrity": "sha512-oz1765PN+imfz1MlZzSZPtC/tqcwsCyIYA8L47EkRnRW97ztRk83SzMiWLrnChC0vqoYxSU1fcFUDA5gV/ZiPg==", "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==",
"dev": true, "dev": true,
"bin": { "bin": {
"tsc": "bin/tsc", "tsc": "bin/tsc",
@ -8096,9 +8096,9 @@
"dev": true "dev": true
}, },
"typescript": { "typescript": {
"version": "4.0.8", "version": "3.9.10",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.8.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz",
"integrity": "sha512-oz1765PN+imfz1MlZzSZPtC/tqcwsCyIYA8L47EkRnRW97ztRk83SzMiWLrnChC0vqoYxSU1fcFUDA5gV/ZiPg==", "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==",
"dev": true "dev": true
}, },
"unbox-primitive": { "unbox-primitive": {

@ -95,7 +95,7 @@
"pretest": "npm run build", "pretest": "npm run build",
"posttest": "agadoo internal/index.mjs", "posttest": "agadoo internal/index.mjs",
"prepublishOnly": "node check_publish_env.js && npm run lint && npm test", "prepublishOnly": "node check_publish_env.js && npm run lint && npm test",
"tsd": "tsc -p src/compiler --emitDeclarationOnly && tsc -p src/runtime --emitDeclarationOnly && node ./post-typegen.js", "tsd": "node ./tsd.js",
"lint": "eslint \"{src,test}/**/*.{ts,js}\"" "lint": "eslint \"{src,test}/**/*.{ts,js}\""
}, },
"repository": { "repository": {

@ -1,14 +0,0 @@
// Svelte 3 types are generated using TS 3.7 . Using newer type syntax is therefore technically a breaking change.
// `export type` / `import type` was introduced later, and needed now in one of the files.
// Replace `export type` with `export` in the `d.ts` file as it doesn't make a difference in `d.ts` files.
// This keeps backwards-compatibility
const fs = require('fs');
const path = 'types/runtime/index.d.ts';
const content = fs.readFileSync(path, 'utf8');
const replaced = content.replace('export type', 'export');
if (content === replaced) {
throw new Error('types/runtime/index.d.ts changed. Update post-typegen.js')
}
fs.writeFileSync(path, replaced);

@ -12,6 +12,6 @@ export {
tick, tick,
createEventDispatcher, createEventDispatcher,
SvelteComponentDev as SvelteComponent, SvelteComponentDev as SvelteComponent,
SvelteComponentTyped SvelteComponentTyped,
// additional exports added through post-typegen.js
} from 'svelte/internal'; } from 'svelte/internal';
export type { SvelteComponentConstructor } from 'svelte/internal';

@ -128,7 +128,7 @@ export interface SvelteComponentDev {
$destroy(): void; $destroy(): void;
[accessor: string]: any; [accessor: string]: any;
} }
interface IComponentOptions<Props extends Record<string, any> = Record<string, any>> { export interface ComponentConstructorParams<Props extends Record<string, any> = Record<string, any>> {
target: Element | ShadowRoot; target: Element | ShadowRoot;
anchor?: Element; anchor?: Element;
props?: Props; props?: Props;
@ -164,7 +164,7 @@ export class SvelteComponentDev extends SvelteComponent {
*/ */
$$slot_def: any; $$slot_def: any;
constructor(options: IComponentOptions) { constructor(options: ComponentConstructorParams) {
if (!options || (!options.target && !options.$$inline)) { if (!options || (!options.target && !options.$$inline)) {
throw new Error("'target' is a required option"); throw new Error("'target' is a required option");
} }
@ -256,26 +256,47 @@ export class SvelteComponentTyped<
*/ */
$$slot_def: Slots; $$slot_def: Slots;
constructor(options: IComponentOptions<Props>) { constructor(options: ComponentConstructorParams<Props>) {
super(options); super(options);
} }
} }
/** /**
* Convenience-type to represent a Svelte component constructor. * Convenience type to get the type of a Svelte component. Useful for example in combination with
* dynamic components and `<svelte:element>`.
* *
* Example: * Example:
* ```ts * ```html
import ASvelteComponent from './ASvelteComponent.svelte'; * <script lang="ts">
const ComponentClass: SvelteComponentConstructor = ASvelteComponent; * import { ComponentType, SvelteComponentTyped } from 'svelte';
new ComponentClass(..); * import Component1 from './Component1.svelte';
``` * import Component2 from './Component2.svelte';
*
* const component: ComponentType = someLogic() ? Component1 : Component2;
* const componentOfCertainSubType: ComponentType<SvelteComponentTyped<{needsThisProp: string}>> = someLogic() ? Component1 : Component2;
* </script>
*
* <svelte:element this={component} />
* <svelte:element this={componentOfCertainSubType} needsThisProp="hello" />
* ```
*/ */
export type SvelteComponentConstructor< export type ComponentType<T extends SvelteComponentTyped = SvelteComponentTyped<any, any, any>> =
Props extends Record<string, any> = any, new (p: ComponentConstructorParams<T extends SvelteComponentTyped<infer X, any, any> ? X : any>) => T;
Events extends Record<string, any> = any,
Slots extends Record<string, any> = any /**
> = new (options: IComponentOptions<Props>) => SvelteComponentTyped<Props, Events, Slots>; * Convenience type to get the properties the given component expects. Example:
* ```html
* <script lang="ts">
* import { ComponentProps } from 'svelte';
* import Component from './Component.svelte';
*
* const props: ComponentProps<Component> = { foo: 'bar' }; // Errors if these aren't the correct props
* </script>
* ```
*/
export type ComponentProps<T extends SvelteComponent> = T extends SvelteComponentTyped<infer Props>
? Props
: unknown;
export function loop_guard(timeout) { export function loop_guard(timeout) {
const start = Date.now(); const start = Date.now();

@ -0,0 +1,13 @@
// This script generates the TypeScript definitions
const { execSync } = require('child_process');
const { readFileSync, writeFileSync } = require('fs');
execSync('tsc -p src/compiler --emitDeclarationOnly && tsc -p src/runtime --emitDeclarationOnly');
// We need to add these types to the index.d.ts here because if we add them before building, the build will fail,
// because the TS->JS transformation doesn't know these exports are types and produces code that fails at runtime.
// We can't use `export type` syntax either because the TS version we're on doesn't have this feature yet.
const path = 'types/runtime/index.d.ts';
const content = readFileSync(path, 'utf8');
writeFileSync(path, content.replace('SvelteComponentTyped', 'SvelteComponentTyped, ComponentType, ComponentConstructorParams, ComponentProps'));
Loading…
Cancel
Save