Skip to main content

其他

TypeScript

你可以在 Svelte 组件中使用 TypeScript。 诸如 Svelte VSCode 扩展 之类的 IDE 扩展将帮助你直接在编辑器中捕获错误,而 svelte-check 在命令行上执行相同的操作,你可以将其集成到 CI 中。

You can use TypeScript within Svelte components. IDE extensions like the Svelte VSCode extension will help you catch errors right in your editor, and svelte-check does the same on the command line, which you can integrate into your CI.

设置(Setup)

要在 Svelte 组件中使用 TypeScript,你需要添加一个预处理器,将 TypeScript 转换为 JavaScript。

To use TypeScript within Svelte components, you need to add a preprocessor that will turn TypeScript into JavaScript.

使用 SvelteKit 或 Vite(Using SvelteKit or Vite)

最简单的开始方法是通过输入 npm create svelte@latest、按照提示并选择 TypeScript 选项来搭建一个新的 SvelteKit 项目。

The easiest way to get started is scaffolding a new SvelteKit project by typing npm create svelte@latest, following the prompts and choosing the TypeScript option.

svelte.config.js
ts
import { vitePreprocess } from '@sveltejs/kit/vite';
const config = {
preprocess: vitePreprocess()
};
export default config;

如果你不需要或不想要 SvelteKit 提供的所有功能,你可以通过输入 npm create vite@latest 并选择 svelte-ts 选项来构建 Svelte 风格的 Vite 项目。

If you don't need or want all the features SvelteKit has to offer, you can scaffold a Svelte-flavoured Vite project instead by typing npm create vite@latest and selecting the svelte-ts option.

svelte.config.js
ts
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
const config = {
preprocess: vitePreprocess()
};
export default config;

在这两种情况下,都会添加 svelte.config.jsvitePreprocess。 Vite/SvelteKit 将从这个配置文件中读取。

In both cases, a svelte.config.js with vitePreprocess will be added. Vite/SvelteKit will read from this config file.

其他构建工具(Other build tools)

如果你使用 Rollup 或 Webpack 等工具,请安装它们各自的 Svelte 插件。 对于 Rollup 来说是 rollup-plugin-svelte,对于 Webpack 来说是 svelte-loader。 对于两者,你需要安装 typescriptsvelte-preprocess 并将预处理器添加到插件配置中(有关更多信息,请参阅各自的自述文件)。 如果你要开始一个新项目,你还可以使用 rollupwebpack 模板通过脚本构建设置。

If you're using tools like Rollup or Webpack instead, install their respective Svelte plugins. For Rollup that's rollup-plugin-svelte and for Webpack that's svelte-loader. For both, you need to install typescript and svelte-preprocess and add the preprocessor to the plugin config (see the respective READMEs for more info). If you're starting a new project, you can also use the rollup or webpack template to scaffold the setup from a script.

如果你要开始一个新项目,我们建议你使用 SvelteKit 或 Vite

<script lang="ts">

要在 Svelte 组件中使用 TypeScript,请将 lang="ts" 添加到 script 标签中:

To use TypeScript inside your Svelte components, add lang="ts" to your script tags:

<script lang="ts">
	let name: string = 'world';

	function greet(name: string) {
		alert(`Hello, ${name}!`);
	}
</script>

属性(Props)

Props 可以直接在 export let 语句上输入:

Props can be typed directly on the export let statement:

<script lang="ts">
	export let name: string;
</script>

插槽(Slots)

Slot 和 slot prop 类型是根据传递给它们的 slot props 的类型推断出来的:

Slot and slot prop types are inferred from the types of the slot props passed to them:

<script lang="ts">
	export let name: string;
</script>

<slot {name} />

<!-- Later -->
<Comp let:name>
	<!--    ^ Inferred as string -->
	{name}
</Comp>

事件(Events)

可以使用 createEventDispatcher 输入事件:

Events can be typed with 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 类型(Enhancing built-in DOM types)

Svelte 尽力提供了所有现有的 HTML DOM 类型。 有时你可能想要使用来自操作的实验属性或自定义事件。 在这些情况下,TypeScript 将抛出类型错误,表示它不知道这些类型。 如果它是一个非实验性的标准属性/事件,这很可能是我们的 HTML 类型 中缺失的类型。 在这种情况下,欢迎你提出问题和/或修复它的 PR。

Svelte provides a best effort of all the HTML DOM types that exist. Sometimes you may want to use experimental attributes or custom events coming from an action. In these cases, TypeScript will throw a type error, saying that it does not know these types. If it's a non-experimental standard attribute/event, this may very well be a missing typing from our HTML typings. In that case, you are welcome to open an issue and/or a PR fixing it.

如果这是自定义或实验属性/事件,你可以像这样增强类型:

In case this is a custom or experimental attribute/event, you can enhance the typings like this:

additional-svelte-typings.d.ts
ts
declare namespace svelteHTML {
// enhance elements
interface IntrinsicElements {
'my-custom-element': { someattribute: string; 'on:event': (e: CustomEvent<any>) => void };
}
// enhance attributes
interface HTMLAttributes<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
}
}

然后确保 d.ts 文件在你的 tsconfig.json.h 文件中被引用。 如果它读取类似 "include": ["src/**/*"] 的内容,并且你的 d.ts 文件位于 src 内,则它应该可以工作。 你可能需要重新加载才能使更改生效。

Then make sure that d.ts file is referenced in your tsconfig.json. If it reads something like "include": ["src/**/*"] and your d.ts file is inside src, it should work. You may need to reload for the changes to take effect.

从 Svelte 版本 4.2 / svelte-check 版本 3.5 / VS Code 扩展版本 107.10.0 开始,你还可以通过增强 svelte/elements 模块来声明类型,如下所示:

Since Svelte version 4.2 / svelte-check version 3.5 / VS Code extension version 107.10.0 you can also declare the typings by augmenting the svelte/elements module like this:

additional-svelte-typings.d.ts
ts
import { HTMLButtonAttributes } from 'svelte/elements';
declare module 'svelte/elements' {
export interface SvelteHTMLElements {
'custom-button': HTMLButtonAttributes;
}
// allows for more granular control over what element to add the typings to
export interface HTMLButtonAttributes {
veryexperimentalattribute?: string;
}
}
export {}; // ensure this is not an ambient module, else types will be overridden instead of augmented

实验性高级类型(Experimental advanced typings)

在更高级的用例中充分利用 TypeScript 会缺少一些功能,例如键入组件实现特定接口、显式键入插槽或使用泛型。 使用实验性的高级类型功能可以实现这些事情。 有关如何使用它们的更多信息,请参阅 这个 RFC

A few features are missing from taking full advantage of TypeScript in more advanced use cases like typing that a component implements a certain interface, explicitly typing slots, or using generics. These things are possible using experimental advanced type capabilities. See this RFC for more information on how to make use of them.

该 API 是实验性的,可能随时更改

限制(Limitations)

标记中没有 TS(No TS in markup)

你不能在模板的标记中使用 TypeScript。 例如,以下内容不起作用:

You cannot use TypeScript in your template's markup. For example, the following does not work:

<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}

反应式声明(Reactive Declarations)

你无法以键入变量的方式使用 TypeScript 键入响应式声明。 例如,以下内容不起作用:

You cannot type your reactive declarations with TypeScript in the way you type a variable. For example, the following does not work:

<script lang="ts">
	let count = 0;

	$: doubled: number = count * 2; // ❌ Does not work
</script>

你无法添加 : TYPE,因为该位置的语法无效。 相反,你可以将定义移至上面的 let 语句:

You cannot add a : TYPE because it's invalid syntax in this position. Instead, you can move the definition to a let statement just above:

<script lang="ts">
	let count = 0;

	let doubled: number;
	$: doubled = count * 2;
</script>

类型(Types)

类型: svelte

上一页 辅助警告