您可以在 Svelte 组件中使用 TypeScript。IDE 扩展,如 [Svelte VS Code 扩展](https://marketplace.visualstudio.com/items?itemName=svelte.svelte-vscode),可以帮助您在编辑器中直接捕获错误,而 [`svelte-check`](https://www.npmjs.com/package/svelte-check) 则在命令行上执行相同的操作,您可以将它集成到您的 CI 中。 ## `` 要在你的 Svelte 组件中使用 TypeScript,请将 `lang="ts"` 添加到你的 `script` 标签中: ```svelte ``` 这样做允许您使用 TypeScript 的*仅类型*功能。也就是说,所有在转换为 JavaScript 时消失的功能,例如类型注解或接口声明。需要 TypeScript 编译器输出实际代码的功能不受支持。这包括: * 使用枚举 * 使用 `private`、`protected` 或 `public` 修饰符在构造函数中与初始化器一起 * 使用尚未成为 ECMAScript 标准部分的功能(即不在 TC39 流程的第 4 级别)并且因此尚未在 Acorn 中实现,这是我们用于解析 JavaScript 的解析器 如果您想使用这些功能之一,您需要设置一个 `脚本` 预处理器。 ## 预处理设置 要使用仅在 TypeScript 中存在的功能在 Svelte 组件中,您需要添加一个将 TypeScript 转换为 JavaScript 的预处理器。 ```ts /// file: svelte.config.js // @noErrors import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; const config = { // Note the additional `{ script: true }` preprocess: vitePreprocess({ script: true }) }; export default config; ``` ### 使用 SvelteKit 或 Vite 最简单的方法是使用命令 `npx sv create` 搭建一个新的 SvelteKit 项目,按照提示操作并选择 TypeScript 选项。 ```ts /// file: svelte.config.js // @noErrors import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; const config = { preprocess: vitePreprocess() }; export default config; ``` 如果您不需要或想要使用 SvelteKit 提供的所有功能,可以通过输入 `npm create vite@latest` 并选择 `svelte-ts` 选项来创建一个具有 Svelte 风格的 Vite 项目。 在两种情况下,都会添加一个 `svelte.config.js`,其中包含 `vitePreprocess`。Vite/SvelteKit 将从这个配置文件中读取。 ### 其他构建工具 如果您正在使用 Rollup 或 Webpack 等工具,请安装它们各自的 Svelte 插件。对于 Rollup,是[rollup-plugin-svelte](https://github.com/sveltejs/rollup-plugin-svelte),对于 Webpack,是[svelte-loader](https://github.com/sveltejs/svelte-loader)。对于两者,您都需要安装`typescript`和`svelte-preprocess`,并将预处理器添加到插件配置中(有关更多信息,请参阅相应的 README)。如果您正在启动一个新项目,也可以使用[rollup](https://github.com/sveltejs/template)或[webpack](https://github.com/sveltejs/template-webpack)模板从脚本中搭建设置。 > \[!注意\] 如果您正在启动一个新项目,我们建议使用 SvelteKit 或 Vite ## tsconfig.json 设置 当使用 TypeScript 时,请确保您的 `tsconfig.json` 设置正确。 * 使用至少 `ES2015` 的 [`目标`](https://www.typescriptlang.org/tsconfig/#target),以便类不会被编译为函数 * 设置 [`verbatimModuleSyntax`](https://www.typescriptlang.org/tsconfig/#verbatimModuleSyntax) 为 `true` 以便将导入保留原样 * 设置 [`isolatedModules`](https://www.typescriptlang.org/tsconfig/#isolatedModules) 为 `true`,以便每个文件都可以独立检查。TypeScript 有一些需要跨文件分析和编译的功能,Svelte 编译器和像 Vite 这样的工具则不提供。 ## 输入: Typing `$props` 输出: 输入: 输入 `$props` 像普通对象一样,输入`$props`,它具有某些属性。 ```svelte ``` ## 通用 `$props` 组件可以声明它们属性之间的泛型关系。一个例子是泛型列表组件,它接收一个项目列表和一个回调属性,该回调属性接收列表中的一个项目。为了声明`items`属性和`select`回调操作的是相同类型,请将`generics`属性添加到`script`标签中: ```svelte {#each items as item} {/each} ``` 内容为`泛型`的部分是你需要在泛型函数的`<...>`标签之间放置的内容。换句话说,你可以使用多个泛型、`extends`和后备类型。 ## 打字包装组件 如果您的组件是包装原生元素,您可能希望向用户公开底层元素的属性。在这种情况下,请使用(或扩展)由 `svelte/elements` 提供的接口之一。以下是一个 `Button` 组件的示例: ```svelte ``` 并非所有元素都有专用的类型定义。对于那些没有定义的,使用 `SvelteHTMLElements`: ```svelte
{@render children?.()}
``` ## 输入: Typing `$state` 输出: 输入:`$state` 您可以将 `$state` 当作任何其他变量来输入。 ```ts let count: number = $state(0); ``` 如果您没有给`$state`赋予初始值,其部分类型将变为`undefined`。 ```ts // @noErrors // Error: Type 'number | undefined' is not assignable to type 'number' let count: number = $state(); ``` 如果您知道变量*将在*您首次使用之前被定义,请使用一个`作为`类型转换。这在类的情况下尤其有用: ```ts class Counter { count = $state() as number; constructor(initial: number) { this.count = initial; } } ``` ## 组件类型 `组件` Svelte 组件属于类型 `Component`。您可以使用它及其相关类型来表达各种约束。 使用动态组件来限制可以传递给它的组件类型: ```svelte ``` > \[!旧版\] 在 Svelte 4 中,组件类型为 `SvelteComponent` 要从组件中提取属性,请使用 `ComponentProps`。 ```ts import type { Component, ComponentProps } from 'svelte'; import MyComponent from './MyComponent.svelte'; function withProps>( component: TComponent, props: ComponentProps ) {} // Errors if the second argument is not the correct props expected // by the component in the first argument. withProps(MyComponent, { foo: 'bar' }); ``` 声明一个变量期望组件的构造函数或实例类型: ```svelte ``` ## 增强内置 DOM 类型 Svelte 尽力提供所有存在的 HTML DOM 类型。有时你可能想使用来自动作的实验性属性或自定义事件。在这些情况下,TypeScript 会抛出类型错误,表示它不知道这些类型。如果它是一个非实验性的标准属性/事件,这可能是我们 [HTML 类型定义](https://github.com/sveltejs/svelte/blob/main/packages/svelte/elements.d.ts) 中缺失的类型。在这种情况下,欢迎你提出问题并/或提交一个修复它的 PR。 如果这是一个自定义或实验性的属性/事件,您可以通过增强 `svelte/elements` 模块来提升类型定义,如下所示: ```ts /// file: additional-svelte-typings.d.ts import { HTMLButtonAttributes } from 'svelte/elements'; declare module 'svelte/elements' { // add a new element export interface SvelteHTMLElements { 'custom-button': HTMLButtonAttributes; } // add a new global attribute that is available on all html elements export interface HTMLAttributes { globalattribute?: string; } // add a new attribute for button elements export interface HTMLButtonAttributes { veryexperimentalattribute?: string; } } export {}; // ensure this is not an ambient module, else types will be overridden instead of augmented ``` 确保在您的 `tsconfig.json` 中引用了 `d.ts` 文件。如果它看起来像这样 `"include": ["src/**/*"]` 并且您的 `d.ts` 文件位于 `src` 中,它应该可以正常工作。您可能需要重新加载以使更改生效。