Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Generate TypeScript definitions for your Svelte components

License

NotificationsYou must be signed in to change notification settings

carbon-design-system/sveld

NPMGitHubnpm downloads to date

sveld is a TypeScript definition generator for Svelte components. It analyzes props, events, slots, and other component features through static analysis. Types and signatures can be defined usingJSDoc notation. The tool can also generate component documentation in Markdown and JSON formats.

The purpose of this project is to make third party Svelte component libraries compatible with the Svelte Language Server and TypeScript with minimal effort required by the author. For example, TypeScript definitions may be used during development via intelligent code completion in Integrated Development Environments (IDE) like VSCode.

Carbon Components Svelte uses this library to auto-generate component types and API metadata:

Please note that the generated TypeScript definitions require Svelte version 3.55 or greater.


Given a Svelte component,sveld can infer basic prop types to generate TypeScript definitions compatible with theSvelte Language Server:

Button.svelte

<script>exportlet type="button";exportlet primary=false;</script><button {...$$restProps} {type}class:primaryon:click>  <slot>Click me</slot></button>

The generated definition extends the officialSvelteComponentTyped interface exported from Svelte.

Button.svelte.d.ts

importtype{SvelteComponentTyped}from"svelte";importtype{SvelteHTMLElements}from"svelte/elements";type$RestProps=SvelteHTMLElements["button"];type$Props={/**   *@default "button"   */type?:string;/**   *@default false   */primary?:boolean;[key: `data-${string}`]:any;};exporttypeButtonProps=Omit<$RestProps,keyof$Props>&$Props;exportdefaultclassButtonextendsSvelteComponentTyped<ButtonProps,{click:WindowEventMap["click"]},{default:{}}>{}

Sometimes, inferring prop types is insufficient.

Prop/event/slot types and signatures can be augmented usingJSDoc notations.

/**@type {"button" | "submit" | "reset"} */exportlettype="button";/** * Set to `true` to use the primary variant */exportletprimary=false;

The accompanying JSDoc annotations would generate the following:

importtype{SvelteHTMLElements}from"svelte/elements";type$RestProps=SvelteHTMLElements["button"];type$Props={/**   *@default "button"   */type?:"button"|"submit"|"reset";/**   * Set to `true` to use the primary variant   *@default false   */primary?:boolean;};exporttypeButtonProps=Omit<$RestProps,keyof$Props>&$Props;exportdefaultclassButtonextendsSvelteComponentTyped<ButtonProps,{click:WindowEventMap["click"]},{default:{}}>{}

Table of Contents

Approach

sveld uses the Svelte compiler to statically analyze Svelte components exported from a library to generate documentation useful to the end user.

Extracted metadata include:

  • props
  • slots
  • forwarded events
  • dispatched events
  • $$restProps

This library adopts a progressively enhanced approach. Any property type that cannot be inferred (e.g., "hello" is a string) falls back to "any" to minimize incorrectly typed properties or signatures. To mitigate this, the library author can add JSDoc annotations to specify types that cannot be reliably inferred. This represents a progressively enhanced approach because JSDocs are comments that can be ignored by the compiler.

Usage

Installation

Installsveld as a development dependency.

# npmnpm i -D sveld# pnpmpnpm i -D sveld# Bunbun i -D sveld# Yarnyarn add -D sveld

Rollup

Import and addsveld as a plugin to yourrollup.config.js.

// rollup.config.jsimportsveltefrom"rollup-plugin-svelte";importresolvefrom"@rollup/plugin-node-resolve";importsveldfrom"sveld";exportdefault{input:"src/index.js",output:{format:"es",file:"lib/index.mjs",},plugins:[svelte(),resolve(),sveld()],};

When building the library, TypeScript definitions are emitted to thetypes folder by default.

Customize the output folder using thetypesOptions.outDir option.

The following example emits the output to thedist folder:

sveld({+  typesOptions: {+    outDir: 'dist'+  }})

Thetests/e2e folder contains example set-ups:

CLI

The CLI uses the"svelte" field from yourpackage.json as the entry point:

npx sveld

Generate documentation in JSON and/or Markdown formats using the following flags:

npx sveld --json --markdown

Node.js

You can also usesveld programmatically in Node.js.

If noinput is specified,sveld will infer the entry point based on thepackage.json#svelte field.

const{ sveld}=require("sveld");constpkg=require("./package.json");sveld({input:"./src/index.js",glob:true,markdown:true,markdownOptions:{onAppend:(type,document,components)=>{if(type==="h1")document.append("quote",`${components.size} components exported from${pkg.name}@${pkg.version}.`);},},json:true,jsonOptions:{outFile:"docs/src/COMPONENT_API.json",},});

jsonOptions.outDir

Ifjson istrue, aCOMPONENT_API.json file will be generated at the root of your project. This file contains documentation for all components.

Use thejsonOptions.outDir option to specify the folder for individual JSON files to be emitted.

sveld({json:true,jsonOptions:{// an individual JSON file will be generated for each component API// e.g. "docs/Button.api.json"outDir:"docs",},});

Publishing to NPM

TypeScript definitions are outputted to thetypes folder by default. Don't forget to include the folder in yourpackage.json when publishing the package to NPM.

{  "svelte": "./src/index.js",  "main": "./lib/index.mjs",+ "types": "./types/index.d.ts",  "files": [    "src",    "lib",+   "types",  ]}

Available Options

By default, only TypeScript definitions are generated.

To generate documentation in Markdown and JSON formats, setmarkdown andjson totrue.

sveld({+  markdown: true,+  json: true,})

API Reference

@type

Without a@type annotation,sveld will infer the primitive type for a prop:

exportletkind="primary";// inferred type: "string"

Use the@type tag to explicitly document the type. In the following example, thekind property has an enumerated (enum) type.

Signature:

/** * Optional description *@type {Type} */

Example:

/** * Specify the kind of button *@type {"primary" | "secondary" | "tertiary"} */exportletkind="primary";/** * Specify the Carbon icon to render *@type {typeof import("carbon-icons-svelte").CarbonIcon} */exportletrenderIcon=Close20;

@typedef

The@typedef tag can be used to define a common type that is used multiple times within a component. All typedefs defined in a component will be exported from the generated TypeScript definition file.

Signature:

/** *@typedef {Type} TypeName */

Example:

/** *@typedef {string} AuthorName *@typedef {{ name?: AuthorName; dob?: string; }} Author *//**@type {Author} */exportletauthor={};/**@type {Author[]} */exportletauthors=[];

@slot

Use the@slot tag for typing component slots. Note that@slot is a non-standard JSDoc tag.

Descriptions are optional for named slots. Currently, the default slot cannot have a description.

Signature:

/** *@slot {Type} slot-name [slot description] */Omitthe`slot-name`totypethedefaultslot./** *@slot {Type} */

Example:

<script>/**   * @slot {{ prop: number; doubled: number; }}   * @slot {{}} title   * @slot {{ prop: number }} body - Customize the paragraph text.*/exportlet prop=0;</script><h1>  <slot {prop}doubled={prop*2} />  <slotname="title" /></h1><p>  <slotname="body" {prop} /></p>

@event

Use the@event tag to type dispatched events. An event name is required and a description optional.

Usenull as the value if no event detail is provided.

Signature:

/** *@event {EventDetail} eventname [event description] */

Example:

/** *@event {{ key: string }} button:key *@event {null} key – Fired when `key` changes. */exportletkey="";import{createEventDispatcher}from"svelte";constdispatch=createEventDispatcher();$:dispatch("button:key",{ key});$:if(key)dispatch("key");

Output:

exportdefaultclassComponentextendsSvelteComponentTyped<ComponentProps,{"button:key":CustomEvent<{key:string}>;/** Fired when `key` changes. */key:CustomEvent<null>;},{}>{}

@restProps

sveld can pick up inline HTML elements that$$restProps is forwarded to. However, it cannot infer the underlying element for instantiated components.

You can use the@restProps tag to specify the element tags that$$restProps is forwarded to.

Signature:

/** * Single element *@restProps {tagname} * * Multiple elements *@restProps {tagname-1 | tagname-2 | tagname-3} */

Example:

<script>/** @restProps {h1 | button}*/exportlet edit=false;importButtonfrom"../";</script>{#ifedit}  <Button {...$$restProps} />{:else}  <h1 {...$$restProps}><slot /></h1>{/if}

@extends

In some cases, a component may be based on another component. The@extends tag can be used to extend generated component props.

Signature:

/** *@extends {<relative path to component>} ComponentProps */

Example:

/**@extends {"./Button.svelte"} ButtonProps */exportconstsecondary=true;importButtonfrom"./Button.svelte";

@generics

Currently, to define generics for a Svelte component, you must usegenerics attribute on the script tag. Note that this feature isexperimental and may change in the future.

However, thegenerics attribute only works if usinglang="ts"; the language server will produce an error ifgenerics is used without specifyinglang="ts".

<!-- This causes an error because `lang="ts"` must be used. --><scriptgenerics="Row extends DataTableRow = any"></script>

Becausesveld is designed to support JavaScript-only usage as a baseline, the API design to specify generics uses a custom JSDoc tag@generics.

Signature:

/** *@generics {GenericParameter} GenericName */

Example

/** *@generics {Row extends DataTableRow = any} Row */

The generated TypeScript definition will resemble the following:

exportdefaultclassComponent<RowextendsDataTableRow=any>extendsSvelteComponentTyped<ComponentProps<Row>,Record<string,any>,Record<string,any>>{}

For a parameter list, the name should be comma-separated but not include spaces.

/** *@generics {Param1, Param2} Name1,Name2 */
exportdefaultclassComponent<Param1,Param2>extendsSvelteComponentTyped<ComponentProps<Name1,Name2>,Record<string,any>,Record<string,any>>{}

@component comments

The Svelte Language Server supports component-level comments through the following syntax:<!-- @component [comment] -->.

sveld will copy these over to the exported default component in the TypeScript definition.

Example:

<!-- @component@example<Button>  Text</Button>--><button>  <slot /></button>

Output:

/** *@example * <Button> *   Text * </Button> */exportdefaultclassButtonextendsSvelteComponentTyped<ButtonProps,{},{default:{}}>{}

Contributing

Refer to thecontributing guidelines.

License

Apache-2.0

About

Generate TypeScript definitions for your Svelte components

Topics

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Sponsor this project

 

Contributors12


[8]ページ先頭

©2009-2025 Movatter.jp