From 4d753d9549777fef73b160e13bc07c0f81a1cec6 Mon Sep 17 00:00:00 2001 From: Carlos Rodrigues Date: Thu, 23 Nov 2023 08:11:01 +0000 Subject: [PATCH 1/8] docs: typescript advanced --- .vitepress/config.ts | 6 +- src/api/general.md | 4 +- src/api/utility-types.md | 18 +++++ src/guide/typescript/advanced.md | 99 +++++++++++++++++++++++++ src/guide/typescript/composition-api.md | 5 +- 5 files changed, 128 insertions(+), 4 deletions(-) create mode 100644 src/guide/typescript/advanced.md diff --git a/.vitepress/config.ts b/.vitepress/config.ts index 7be2308b6f..849f092646 100644 --- a/.vitepress/config.ts +++ b/.vitepress/config.ts @@ -286,6 +286,10 @@ export const sidebar: ThemeConfig['sidebar'] = { { text: 'TS with Options API', link: '/guide/typescript/options-api' + }, + { + text: 'Typescript: Advanced', + link: '/guide/typescript/advanced' } ] }, @@ -700,7 +704,7 @@ export default defineConfigWithTheme({ markdown: { config(md) { md.use(headerPlugin) - // .use(textAdPlugin) + // .use(textAdPlugin) } }, diff --git a/src/api/general.md b/src/api/general.md index 80eec455f9..51ed7c25ed 100644 --- a/src/api/general.md +++ b/src/api/general.md @@ -124,9 +124,11 @@ A type helper for defining a Vue component with type inference. You can extract the instance type of a component (equivalent to the type of `this` in its options) from the return type of `defineComponent()` like this: ```ts + import { ComponentInstance } from 'vue' + const Foo = defineComponent(/* ... */) - type FooInstance = InstanceType + type FooInstance = ComponentInstance ``` ### Function Signature {#function-signature} diff --git a/src/api/utility-types.md b/src/api/utility-types.md index d91655a631..c90dfd7727 100644 --- a/src/api/utility-types.md +++ b/src/api/utility-types.md @@ -104,6 +104,24 @@ Extract prop types from a runtime props options object. The extracted types are // } ``` +## ComponentInstance {#componentinstance} + +Used to extract the instance type of a component (equivalent to the type of `this` in its options). + +- **Example** + +```vue + + +``` + ## ComponentCustomProperties {#componentcustomproperties} Used to augment the component instance type to support custom global properties. diff --git a/src/guide/typescript/advanced.md b/src/guide/typescript/advanced.md new file mode 100644 index 0000000000..0f0b03ff45 --- /dev/null +++ b/src/guide/typescript/advanced.md @@ -0,0 +1,99 @@ +# Typescript: advanced + +> This page assumes you've already read the overview on [Using Vue with TypeScript](./overview), Essentials and Components in-Depth. +> + +## Components + +Components are hard to fully understand, even when reading the source-code or looking for examples. This section will explain more advanced topics and some use cases for some of the API's. + +### What's a component in typescript? + +> For what's a component please check [Components Basics](./../essentials/component-basics) + +For the examples we will be using [defineComponent](./../../api/general.html#definecomponent), it makes it easier to explain, same concepts are valid for [Single-File Components](./../../guide/scaling-up/sfc). + +```ts +const Comp = defineComponent({ + /* ... */ +}) +``` + +In terms of typing Vue components are mainly composed by 3 parts: + +#### Options + +Used to declare the component's `props`, `emits`, `slots`, etc. + +```ts +defineComponent({ + props: { + msg: String + }, + emits: { + clicked: (msg: string) => true + }, + methods: { + onClick() { + this.$emit('clicked', this.msg) + } + } +}) +``` + +#### Instance + +Component's context (`this`) and retuned by [ComponentInstance](./../../api/utility-types#componentinstance) + +```ts +const Comp = defineComponent({ + props: { + msg: String + }, + emits: { + clicked: (msg: string) => true + }, + methods: { + onClick() { + // this.msg is typed as string + this.$emit('clicked', this.msg) + } + } +}) + +const compEl = ref>() + +compEl.value.msg //string +compEl.value.onClick // function +``` + +### Render + +Contract to render the component, eg: `props` and `slots`. + +In this example we will use [h](../../api/render-function.md); + +```ts +const Comp = defineComponent({ + props: { + msg: String + }, + emits: { + clicked: (msg: string) => true + }, + methods: { + onClick() { + // this.msg is typed as string + this.$emit('clicked', this.msg) + } + } +}) + +// the second argument is the render contract. +h(Comp, { + msg: 'hello', + onClick: () => { + // button clicked + } +}) +``` diff --git a/src/guide/typescript/composition-api.md b/src/guide/typescript/composition-api.md index 65b94a58d1..e8c8c2fc86 100644 --- a/src/guide/typescript/composition-api.md +++ b/src/guide/typescript/composition-api.md @@ -374,14 +374,15 @@ defineExpose({ ``` -In order to get the instance type of `MyModal`, we need to first get its type via `typeof`, then use TypeScript's built-in `InstanceType` utility to extract its instance type: +In order to get the instance type of `MyModal`, we need to first get its type via `typeof`, then use Vue provided `ComponentInstance` utility to extract its instance type: ```vue{5}