From a8e616be7803f1aeec0a9a0a7cd4655edb1b69c3 Mon Sep 17 00:00:00 2001 From: Simon Date: Tue, 28 Jun 2022 12:20:08 +0200 Subject: [PATCH] Adjust way of adding types to output, add more convenience types Closes #7584 --- package-lock.json | 14 +++++------ package.json | 2 +- post-typegen.js | 14 ----------- src/runtime/index.ts | 4 +-- src/runtime/internal/dev.ts | 49 ++++++++++++++++++++++++++----------- tsd.js | 13 ++++++++++ 6 files changed, 58 insertions(+), 38 deletions(-) delete mode 100644 post-typegen.js create mode 100644 tsd.js diff --git a/package-lock.json b/package-lock.json index fedd7ad74a..83d963b827 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,7 +44,7 @@ "sourcemap-codec": "^1.4.8", "tiny-glob": "^0.2.6", "tslib": "^2.0.3", - "typescript": "~4.0.0" + "typescript": "^3.7.5" }, "engines": { "node": ">= 8" @@ -4402,9 +4402,9 @@ "dev": true }, "node_modules/typescript": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.8.tgz", - "integrity": "sha512-oz1765PN+imfz1MlZzSZPtC/tqcwsCyIYA8L47EkRnRW97ztRk83SzMiWLrnChC0vqoYxSU1fcFUDA5gV/ZiPg==", + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", + "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", "dev": true, "bin": { "tsc": "bin/tsc", @@ -8096,9 +8096,9 @@ "dev": true }, "typescript": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.0.8.tgz", - "integrity": "sha512-oz1765PN+imfz1MlZzSZPtC/tqcwsCyIYA8L47EkRnRW97ztRk83SzMiWLrnChC0vqoYxSU1fcFUDA5gV/ZiPg==", + "version": "3.9.10", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.10.tgz", + "integrity": "sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q==", "dev": true }, "unbox-primitive": { diff --git a/package.json b/package.json index 0e37745063..000f4cd2e7 100644 --- a/package.json +++ b/package.json @@ -95,7 +95,7 @@ "pretest": "npm run build", "posttest": "agadoo internal/index.mjs", "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}\"" }, "repository": { diff --git a/post-typegen.js b/post-typegen.js deleted file mode 100644 index 08d932d090..0000000000 --- a/post-typegen.js +++ /dev/null @@ -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); diff --git a/src/runtime/index.ts b/src/runtime/index.ts index ca611685be..39bf7a9496 100644 --- a/src/runtime/index.ts +++ b/src/runtime/index.ts @@ -12,6 +12,6 @@ export { tick, createEventDispatcher, SvelteComponentDev as SvelteComponent, - SvelteComponentTyped + SvelteComponentTyped, + // additional exports added through post-typegen.js } from 'svelte/internal'; -export type { SvelteComponentConstructor } from 'svelte/internal'; diff --git a/src/runtime/internal/dev.ts b/src/runtime/internal/dev.ts index 0dba0ec1fa..d6987990c6 100644 --- a/src/runtime/internal/dev.ts +++ b/src/runtime/internal/dev.ts @@ -128,7 +128,7 @@ export interface SvelteComponentDev { $destroy(): void; [accessor: string]: any; } -interface IComponentOptions = Record> { +export interface ComponentConstructorParams = Record> { target: Element | ShadowRoot; anchor?: Element; props?: Props; @@ -164,7 +164,7 @@ export class SvelteComponentDev extends SvelteComponent { */ $$slot_def: any; - constructor(options: IComponentOptions) { + constructor(options: ComponentConstructorParams) { if (!options || (!options.target && !options.$$inline)) { throw new Error("'target' is a required option"); } @@ -256,26 +256,47 @@ export class SvelteComponentTyped< */ $$slot_def: Slots; - constructor(options: IComponentOptions) { + constructor(options: ComponentConstructorParams) { 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 ``. * * Example: - * ```ts - import ASvelteComponent from './ASvelteComponent.svelte'; - const ComponentClass: SvelteComponentConstructor = ASvelteComponent; - new ComponentClass(..); - ``` + * ```html + * + * + * + * + * ``` */ -export type SvelteComponentConstructor< - Props extends Record = any, - Events extends Record = any, - Slots extends Record = any -> = new (options: IComponentOptions) => SvelteComponentTyped; +export type ComponentType> = + new (p: ComponentConstructorParams ? X : any>) => T; + +/** + * Convenience type to get the properties the given component expects. Example: + * ```html + * + * ``` + */ +export type ComponentProps = T extends SvelteComponentTyped + ? Props + : unknown; export function loop_guard(timeout) { const start = Date.now(); diff --git a/tsd.js b/tsd.js new file mode 100644 index 0000000000..ad3e74f95c --- /dev/null +++ b/tsd.js @@ -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'));