您可以在 Svelte 元件中使用 TypeScript。IDE 擴充功能(例如 Svelte VSCode 擴充功能)將幫助您在編輯器中直接找出錯誤,而 svelte-check
則會在命令列中執行相同的動作,您可以將其整合到 CI 中。
設定永久連結
要在 Svelte 元件中使用 TypeScript,您需要新增一個預處理器,它會將 TypeScript 轉換成 JavaScript。
使用 SvelteKit 或 Vite永久連結
入門最簡單的方法是透過輸入 npm create svelte@latest
來建立一個新的 SvelteKit 專案,並依照提示選擇 TypeScript 選項。
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,請將 lang="ts"
新增到你的 script
標籤
<script lang="ts">
let name: string = 'world';
function greet(name: string) {
alert(`Hello, ${name}!`);
}
</script>
屬性永久連結
屬性可以直接輸入在 export let
聲明中
<script lang="ts">
export let name: string;
</script>
插槽永久連結
插槽和插槽屬性類型會從傳遞給它們的插槽屬性類型中推論出來
<script lang="ts">
export let name: string;
</script>
<slot {name} />
<!-- Later -->
<Comp let:name>
<!-- ^ Inferred as string -->
{name}
</Comp>
事件永久連結
事件可以用 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)就可以提供 IntelliSense,並在 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> {}