diff --git a/src/guide/typescript/composition-api.md b/src/guide/typescript/composition-api.md index 35085e1e..abdf463b 100644 --- a/src/guide/typescript/composition-api.md +++ b/src/guide/typescript/composition-api.md @@ -1,12 +1,12 @@ -# TypeScript 与组合式 API {#typescript-with-composition-api} +# TypeScript 與組合式 API {#typescript-with-composition-api} -> 这一章假设你已经阅读了[搭配 TypeScript 使用 Vue](./overview) 的概览。 +> 這一章假設你已經閱讀了[搭配 TypeScript 使用 Vue](./overview) 的概覽。 -## 为组件的 props 标注类型 {#typing-component-props} +## 為組件的 props 標註類型 {#typing-component-props} ### 使用 ` ``` -这被称之为“运行时声明”,因为传递给 `defineProps()` 的参数会作为运行时的 `props` 选项使用。 +這被稱之為“運行時聲明”,因為傳遞給 `defineProps()` 的參數會作為運行時的 `props` 選項使用。 -然而,通过泛型参数来定义 props 的类型通常更直接: +然而,通過泛型參數來定義 props 的類型通常更直接: ```vue ``` -这被称之为“基于类型的声明”。编译器会尽可能地尝试根据类型参数推导出等价的运行时选项。在这种场景下,我们第二个例子中编译出的运行时选项和第一个是完全一致的。 +這被稱之為“基於類型的聲明”。編譯器會盡可能地嘗試根據類型參數推導出等價的運行時選項。在這種場景下,我們第二個例子中編譯出的運行時選項和第一個是完全一致的。 -基于类型的声明或者运行时声明可以择一使用,但是不能同时使用。 +基於類型的聲明或者運行時聲明可以擇一使用,但是不能同時使用。 -我们也可以将 props 的类型移入一个单独的接口中: +我們也可以將 props 的類型移入一個單獨的接口中: ```vue ``` -这同样适用于 `Props` 从另一个源文件中导入的情况。该功能要求 TypeScript 作为 Vue 的一个 peer dependency。 +這同樣適用於 `Props` 從另一個源文件中導入的情況。該功能要求 TypeScript 作為 Vue 的一個 peer dependency。 ```vue ``` -#### 语法限制 {#syntax-limitations} +#### 語法限制 {#syntax-limitations} -在 3.2 及以下版本中,`defineProps()` 的泛型类型参数仅限于类型文字或对本地接口的引用。 +在 3.2 及以下版本中,`defineProps()` 的泛型類型參數僅限於類型文字或對本地接口的引用。 -这个限制在 3.3 中得到了解决。最新版本的 Vue 支持在类型参数位置引用导入和有限的复杂类型。但是,由于类型到运行时转换仍然基于 AST,一些需要实际类型分析的复杂类型,例如条件类型,还未支持。您可以使用条件类型来指定单个 prop 的类型,但不能用于整个 props 对象的类型。 +這個限制在 3.3 中得到了解決。最新版本的 Vue 支持在類型參數位置引用導入和有限的複雜類型。但是,由於類型到運行時轉換仍然基於 AST,一些需要實際類型分析的複雜類型,例如條件類型,還未支持。您可以使用條件類型來指定單個 prop 的類型,但不能用於整個 props 對象的類型。 -### Props 解构默认值 {#props-default-values} +### Props 解構默認值 {#props-default-values} -当使用基于类型的声明时,我们失去了为 props 声明默认值的能力。这可以通过 `withDefaults` 编译器宏解决: +當使用基於類型的聲明時,我們失去了為 props 聲明默認值的能力。這可以通過 `withDefaults` 編譯器宏解決: ```ts export interface Props { @@ -82,11 +82,11 @@ const props = withDefaults(defineProps(), { }) ``` -这将被编译为等效的运行时 props `default` 选项。此外,`withDefaults` 帮助程序为默认值提供类型检查,并确保返回的 props 类型删除了已声明默认值的属性的可选标志。 +這將被編譯為等效的運行時 props `default` 選項。此外,`withDefaults` 幫助程序為默認值提供類型檢查,並確保返回的 props 類型刪除了已聲明默認值的屬性的可選標誌。 -### 非 ` ``` -对于运行时声明,我们可以使用 `PropType` 工具类型: +對於運行時聲明,我們可以使用 `PropType` 工具類型: ```ts import type { PropType } from 'vue' @@ -129,7 +129,7 @@ const props = defineProps({ }) ``` -其工作方式与直接指定 `props` 选项基本相同: +其工作方式與直接指定 `props` 選項基本相同: ```ts import { defineComponent } from 'vue' @@ -142,36 +142,36 @@ export default defineComponent({ }) ``` -`props` 选项通常用于 Options API,因此你会在[选项式 API 与 TypeScript](/guide/typescript/options-api#typing-component-props) 指南中找到更详细的例子。这些例子中展示的技术也适用于使用 `defineProps()` 的运行时声明。 +`props` 選項通常用於 Options API,因此你會在[選項式 API 與 TypeScript](/guide/typescript/options-api#typing-component-props) 指南中找到更詳細的例子。這些例子中展示的技術也適用於使用 `defineProps()` 的運行時聲明。 -## 为组件的 emits 标注类型 {#typing-component-emits} +## 為組件的 emits 標註類型 {#typing-component-emits} -在 ` ``` -类型参数可以是以下的一种: +類型參數可以是以下的一種: -1. 一个可调用的函数类型,但是写作一个包含[调用签名](https://www.typescriptlang.org/docs/handbook/2/functions.html#call-signatures)的类型字面量。它将被用作返回的 `emit` 函数的类型。 -2. 一个类型字面量,其中键是事件名称,值是数组或元组类型,表示事件的附加接受参数。上面的示例使用了具名元组,因此每个参数都可以有一个显式的名称。 +1. 一個可調用的函數類型,但是寫作一個包含[調用簽名](https://www.typescriptlang.org/docs/handbook/2/functions.html#call-signatures)的類型字面量。它將被用作返回的 `emit` 函數的類型。 +2. 一個類型字面量,其中鍵是事件名稱,值是數組或元組類型,表示事件的附加接受參數。上面的示例使用了具名元組,因此每個參數都可以有一個顯式的名稱。 -我们可以看到,基于类型的声明使我们可以对所触发事件的类型进行更细粒度的控制。 +我們可以看到,基於類型的聲明使我們可以對所觸發事件的類型進行更細粒度的控制。 -若没有使用 ` @@ -309,7 +309,7 @@ function handleChange(event) { ``` -没有类型标注时,这个 `event` 参数会隐式地标注为 `any` 类型。这也会在 `tsconfig.json` 中配置了 `"strict": true` 或 `"noImplicitAny": true` 时报出一个 TS 错误。因此,建议显式地为事件处理函数的参数标注类型。此外,你在访问 `event` 上的属性时可能需要使用类型断言: +沒有類型標註時,這個 `event` 參數會隱式地標註為 `any` 類型。這也會在 `tsconfig.json` 中配置了 `"strict": true` 或 `"noImplicitAny": true` 時報出一個 TS 錯誤。因此,建議顯式地為事件處理函數的參數標註類型。此外,你在訪問 `event` 上的屬性時可能需要使用類型斷言: ```ts function handleChange(event: Event) { @@ -317,9 +317,9 @@ function handleChange(event: Event) { } ``` -## 为 provide / inject 标注类型 {#typing-provide-inject} +## 為 provide / inject 標註類型 {#typing-provide-inject} -provide 和 inject 通常会在不同的组件中运行。要正确地为注入的值标记类型,Vue 提供了一个 `InjectionKey` 接口,它是一个继承自 `Symbol` 的泛型类型,可以用来在提供者和消费者之间同步注入值的类型: +provide 和 inject 通常會在不同的組件中運行。要正確地為注入的值標記類型,Vue 提供了一個 `InjectionKey` 接口,它是一個繼承自 `Symbol` 的泛型類型,可以用來在提供者和消費者之間同步注入值的類型: ```ts import { provide, inject } from 'vue' @@ -327,36 +327,36 @@ import type { InjectionKey } from 'vue' const key = Symbol() as InjectionKey -provide(key, 'foo') // 若提供的是非字符串值会导致错误 +provide(key, 'foo') // 若提供的是非字符串值會導致錯誤 -const foo = inject(key) // foo 的类型:string | undefined +const foo = inject(key) // foo 的類型:string | undefined ``` -建议将注入 key 的类型放在一个单独的文件中,这样它就可以被多个组件导入。 +建議將注入 key 的類型放在一個單獨的文件中,這樣它就可以被多個組件導入。 -当使用字符串注入 key 时,注入值的类型是 `unknown`,需要通过泛型参数显式声明: +當使用字符串注入 key 時,注入值的類型是 `unknown`,需要通過泛型參數顯式聲明: ```ts -const foo = inject('foo') // 类型:string | undefined +const foo = inject('foo') // 類型:string | undefined ``` -注意注入的值仍然可以是 `undefined`,因为无法保证提供者一定会在运行时 provide 这个值。 +注意注入的值仍然可以是 `undefined`,因為無法保證提供者一定會在運行時 provide 這個值。 -当提供了一个默认值后,这个 `undefined` 类型就可以被移除: +當提供了一個默認值後,這個 `undefined` 類型就可以被移除: ```ts -const foo = inject('foo', 'bar') // 类型:string +const foo = inject('foo', 'bar') // 類型:string ``` -如果你确定该值将始终被提供,则还可以强制转换该值: +如果你確定該值將始終被提供,則還可以強制轉換該值: ```ts const foo = inject('foo') as string ``` -## 为模板引用标注类型 {#typing-template-refs} +## 為模板引用標註類型 {#typing-template-refs} -模板引用需要通过一个显式指定的泛型参数和一个初始值 `null` 来创建: +模板引用需要通過一個顯式指定的泛型參數和一個初始值 `null` 來創建: ```vue ``` -为了获取 `MyModal` 的类型,我们首先需要通过 `typeof` 得到其类型,再使用 TypeScript 内置的 `InstanceType` 工具类型来获取其实例类型: +為了獲取 `MyModal` 的類型,我們首先需要通過 `typeof` 得到其類型,再使用 TypeScript 內置的 `InstanceType` 工具類型來獲取其實例類型: ```vue{5} @@ -411,7 +411,7 @@ const openModal = () => { ``` -如果组件的具体类型无法获得,或者你并不关心组件的具体类型,那么可以使用 `ComponentPublicInstance`。这只会包含所有组件都共享的属性,比如 `$el`。 +如果組件的具體類型無法獲得,或者你並不關心組件的具體類型,那麼可以使用 `ComponentPublicInstance`。這隻會包含所有組件都共享的屬性,例如 `$el`。 ```ts import { ref } from 'vue'