From 7e664dc656ade344b6352e8ee26bdc6fa34626b2 Mon Sep 17 00:00:00 2001 From: Eric Liu Date: Sat, 20 Apr 2024 13:58:34 -0700 Subject: [PATCH] feat(component-parser): support generics --- src/ComponentParser.ts | 9 +++++++++ src/writer/writer-ts-definitions.ts | 21 ++++++++++++++++----- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/src/ComponentParser.ts b/src/ComponentParser.ts index d7e8427f..ab310636 100644 --- a/src/ComponentParser.ts +++ b/src/ComponentParser.ts @@ -81,6 +81,8 @@ interface TypeDef { ts: string; } +type ComponentGenerics = [name: string, type: string]; + interface ComponentInlineElement { type: "InlineComponent"; name: string; @@ -108,6 +110,7 @@ export interface ParsedComponent { slots: ComponentSlot[]; events: ComponentEvent[]; typedefs: TypeDef[]; + generics: null | ComponentGenerics; rest_props: RestProps; extends?: Extends; componentComment?: string; @@ -128,6 +131,7 @@ export default class ComponentParser { private readonly slots: Map = new Map(); private readonly events: Map = new Map(); private readonly typedefs: Map = new Map(); + private readonly generics: ComponentGenerics = null; private readonly bindings: Map = new Map(); constructor(options?: ComponentParserOptions) { @@ -311,6 +315,9 @@ export default class ComponentParser { ts: /(\}|\};)$/.test(type) ? `interface ${name} ${type}` : `type ${name} = ${type}`, }); break; + case "generics": + this.generics = [name, type]; + break; } }); }); @@ -329,6 +336,7 @@ export default class ComponentParser { this.slots.clear(); this.events.clear(); this.typedefs.clear(); + this.generics = null; this.bindings.clear(); } @@ -732,6 +740,7 @@ export default class ComponentParser { }), events: ComponentParser.mapToArray(this.events), typedefs: ComponentParser.mapToArray(this.typedefs), + generics: this.generics, rest_props: this.rest_props, extends: this.extends, componentComment: this.componentComment, diff --git a/src/writer/writer-ts-definitions.ts b/src/writer/writer-ts-definitions.ts index f891b821..34e4d403 100644 --- a/src/writer/writer-ts-definitions.ts +++ b/src/writer/writer-ts-definitions.ts @@ -33,7 +33,7 @@ function addCommentLine(value: any, returnValue?: any) { return `* ${returnValue || value}\n`; } -function genPropDef(def: Pick) { +function genPropDef(def: Pick) { const initial_props = def.props .filter((prop) => !prop.isFunctionDeclaration && prop.kind !== "const") .map((prop) => { @@ -68,6 +68,8 @@ function genPropDef(def: Pick` : ""; + if (def.rest_props?.type === "Element") { const extend_tag_map = def.rest_props.name .split("|") @@ -88,7 +90,9 @@ function genPropDef(def: Pick` : ""; + const genericProps = generics ? `${props_name}<${generics[0]}>` : props_name; + return ` import type { SvelteComponentTyped } from "svelte";${ rest_props?.type === "Element" ? `import type { SvelteHTMLElements } from "svelte/elements";\n` : "" @@ -227,8 +238,8 @@ export function writeTsDefinition(component: ComponentDocApi) { ${getTypeDefs({ typedefs })} ${prop_def} ${genComponentComment({ componentComment })} - export default class ${moduleName === "default" ? "" : moduleName} extends SvelteComponentTyped< - ${props_name}, + export default class ${moduleName === "default" ? "" : moduleName}${generic} extends SvelteComponentTyped< + ${genericProps}, ${genEventDef({ events })}, {${genSlotDef({ slots })}} > {