您可以在 Svelte 组件中使用 TypeScript。IDE 扩展(例如 Svelte VSCode 扩展)将帮助您在编辑器中捕获错误,而 svelte-check
在命令行中执行相同的操作,您可以将其集成到 CI 中。
设置永久链接
要在 Svelte 组件中使用 TypeScript,您需要添加一个预处理器,该预处理器将 TypeScript 转换为 JavaScript。
使用 SvelteKit 或 Vite永久链接
入门的最简单方法是通过键入 npm create svelte@latest
,按照提示并选择 TypeScript 选项来构建一个新的 SvelteKit 项目。
ts
import {vitePreprocess } from '@sveltejs/kit/vite';constconfig = {preprocess :vitePreprocess ()};export defaultconfig ;
如果您不需要或不想要 SvelteKit 提供的所有功能,则可以通过键入 npm create vite@latest
并选择 svelte-ts
选项来构建一个 Svelte 风格的 Vite 项目。
ts
import {vitePreprocess } from '@sveltejs/vite-plugin-svelte';constconfig = {preprocess :vitePreprocess ()};export defaultconfig ;
在两种情况下,都会添加带有 vitePreprocess
的 svelte.config.js
。Vite/SvelteKit 将从这个配置文件中读取。
其他构建工具永久链接
如果你使用的是 Rollup 或 Webpack 等工具,请安装它们各自的 Svelte 插件。对于 Rollup,是 rollup-plugin-svelte,对于 Webpack,是 svelte-loader。对于两者,你需要安装 typescript
和 svelte-preprocess
,并将预处理器添加到插件配置中(有关更多信息,请参阅各自的 README)。如果你正在启动一个新项目,你还可以使用 rollup 或 webpack 模板从脚本中构建设置。
如果你正在启动一个新项目,我们建议你使用 SvelteKit 或 Vite
<script lang="ts">永久链接
要在 Svelte 组件中使用 TypeScript,请在 script
标签中添加 lang="ts"
<script lang="ts">
let name: string = 'world';
function greet(name: string) {
alert(`Hello, ${name}!`);
}
</script>
Props永久链接
Props 可以直接在 export let
语句中输入
<script lang="ts">
export let name: string;
</script>
Slots永久链接
Slot 和 slot prop 类型是从传递给它们的 slot prop 类型推断出来的
<script lang="ts">
export let name: string;
</script>
<slot {name} />
<!-- Later -->
<Comp let:name>
<!-- ^ Inferred as string -->
{name}
</Comp>
Events永久链接
事件可以使用 createEventDispatcher
输入
<script lang="ts">
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher<{
event: null; // does not accept a payload
click: string; // has a required string payload
type: string | null; // has an optional string payload
}>();
function handleClick() {
dispatch('event');
dispatch('click', 'hello');
}
function handleType() {
dispatch('event');
dispatch('type', Math.random() > 0.5 ? 'world' : null);
}
</script>
<button on:click={handleClick} on:keydown={handleType}>Click</button>
增强内置 DOM 类型永久链接
Svelte 提供了所有现有的 HTML DOM 类型的最佳尝试。有时你可能希望使用来自操作的实验性属性或自定义事件。在这些情况下,TypeScript 将抛出一个类型错误,表示它不知道这些类型。如果它是一个非实验性标准属性/事件,这很可能是我们的 HTML 类型 中缺少类型。在这种情况下,欢迎你提出问题和/或修复它的 PR。
如果这是一个自定义或实验性属性/事件,你可以像这样增强类型
ts
declare namespacesvelteHTML {// enhance elementsinterfaceIntrinsicElements {'my-custom-element': {someattribute : string; 'on:event': (e :CustomEvent <any>) => void };}// enhance attributesinterfaceHTMLAttributes <T > {// If you want to use on:beforeinstallprompt'on:beforeinstallprompt'?: (event : any) => any;// If you want to use myCustomAttribute={..} (note: all lowercase)mycustomattribute ?: any; // You can replace any with something more specific if you like}}
然后确保在你的 tsconfig.json
中引用了 d.ts
文件。如果它读起来像 "include": ["src/**/*"]
并且你的 d.ts
文件在 src
中,它应该可以工作。你可能需要重新加载才能使更改生效。
从 Svelte 版本 4.2 / svelte-check
版本 3.5 / VS Code 扩展版本 107.10.0 开始,你还可以通过像这样扩展 svelte/elements
模块来声明类型
ts
import {HTMLButtonAttributes } from 'svelte/elements';declare module 'svelte/elements' {export interfaceSvelteHTMLElements {'custom-button':HTMLButtonAttributes ;}// allows for more granular control over what element to add the typings toexport interfaceHTMLButtonAttributes {veryexperimentalattribute ?: string;}}export {}; // ensure this is not an ambient module, else types will be overridden instead of augmented
实验性高级类型永久链接
在更高级的用例中充分利用 TypeScript 的一些功能还缺失,比如为组件实现某个接口、明确指定插槽类型或使用泛型。使用实验性高级类型功能可以实现这些功能。请参阅 此 RFC 了解更多有关如何使用它们的信息。
该 API 是实验性的,并且随时可能更改
限制永久链接
标记中没有 TS永久链接
你无法在模板的标记中使用 TypeScript。例如,以下代码不起作用
<script lang="ts">
let count = 10;
</script>
<h1>Count as string: {count as string}!</h1> <!-- ❌ Does not work -->
{#if count > 4}
{@const countString: string = count} <!-- ❌ Does not work -->
{countString}
{/if}
响应式声明永久链接
你无法使用 TypeScript 为响应式声明指定类型,就像为变量指定类型一样。例如,以下代码不起作用
<script lang="ts">
let count = 0;
$: doubled: number = count * 2; // ❌ Does not work
</script>
你无法添加 : TYPE
,因为它在此位置是无效语法。相反,你可以将定义移动到正上方的 let
语句
<script lang="ts">
let count = 0;
let doubled: number;
$: doubled = count * 2;
</script>
类型永久链接
ComponentConstructorOptions永久链接
ts
interface ComponentConstructorOptions<Props extends Record<string, any> = Record<string, any>> {…}
ts
target: Element | Document | ShadowRoot;
ts
anchor?: Element;
ts
props?: Props;
ts
context?: Map<any, any>;
ts
hydrate?: boolean;
ts
intro?: boolean;
ts
$$inline?: boolean;
ComponentEvents永久链接
便捷类型,用于获取给定组件期望的事件。示例
<script lang="ts">
import type { ComponentEvents } from 'svelte';
import Component from './Component.svelte';
function handleCloseEvent(event: ComponentEvents<Component>['close']) {
console.log(event.detail);
}
</script>
<Component on:close={handleCloseEvent} />
ts
type ComponentEvents<Component extends SvelteComponent_1> =Component extends SvelteComponent<any, infer Events>? Events: never;
ComponentProps永久链接
便捷类型,用于获取给定组件期望的属性。示例
<script lang="ts">
import type { ComponentProps } from 'svelte';
import Component from './Component.svelte';
const props: ComponentProps<Component> = { foo: 'bar' }; // Errors if these aren't the correct props
</script>
ts
type ComponentProps<Component extends SvelteComponent_1> =Component extends SvelteComponent<infer Props>? Props: never;
ComponentType永久链接
便捷类型,用于获取 Svelte 组件的类型。例如,与使用 <svelte:component>
的动态组件结合使用时很有用。
示例
<script lang="ts">
import type { ComponentType, SvelteComponent } from 'svelte';
import Component1 from './Component1.svelte';
import Component2 from './Component2.svelte';
const component: ComponentType = someLogic() ? Component1 : Component2;
const componentOfCertainSubType: ComponentType<SvelteComponent<{ needsThisProp: string }>> = someLogic() ? Component1 : Component2;
</script>
<svelte:component this={component} />
<svelte:component this={componentOfCertainSubType} needsThisProp="hello" />
ts
type ComponentType<Component extends SvelteComponent = SvelteComponent> = (new (options: ComponentConstructorOptions<Component extends SvelteComponent<infer Props>? Props: Record<string, any>>) => Component) & {/** The custom element version of the component. Only present if compiled with the `customElement` compiler option */element?: typeof HTMLElement;};
SvelteComponent永久链接
具有某些次要开发增强功能的 Svelte 组件的基类。在 dev=true 时使用。
可用于创建强类型 Svelte 组件。
示例:永久链接
你在 npm 上有一个名为 component-library
的组件库,从中导出了一个名为 MyComponent
的组件。对于 Svelte+TypeScript 用户,你希望提供类型定义。因此你创建了一个 index.d.ts
ts
import {SvelteComponent } from "svelte";export classMyComponent extendsSvelteComponent <{foo : string}> {}
输入此类型定义后,带有 Svelte 扩展的 IDE(如 VS Code)就可以提供智能感知,并在 Svelte 文件中使用 TypeScript 组件
<script lang="ts">
import { MyComponent } from "component-library";
</script>
<MyComponent foo={'bar'} />
ts
class SvelteComponent<Props extends Record<string, any> = any,Events extends Record<string, any> = any,Slots extends Record<string, any> = any> extends SvelteComponent_1<Props, Events> {…}
ts
[prop: string]: any;
ts
constructor(options: ComponentConstructorOptions<Props>);
ts
$capture_state(): void;
ts
$inject_state(): void;
SvelteComponentTyped永久链接
改为使用
SvelteComponent
。有关更多信息,请参阅 PR:https://github.com/sveltejs/svelte/pull/8512
ts
class SvelteComponentTyped<Props extends Record<string, any> = any,Events extends Record<string, any> = any,Slots extends Record<string, any> = any> extends SvelteComponent<Props, Events, Slots> {}