diff --git a/README.md b/README.md
index 42d4e71..0d7ea93 100644
--- a/README.md
+++ b/README.md
@@ -3,6 +3,7 @@
Cheatsheets for experienced Vue developers getting started with TypeScript.
- [Vue 3 specifics](vue-3.md)
+- [Class Components & Decorators](class-components.md)
# Section 1: Setup
@@ -87,66 +88,6 @@ const Component = defineComponent({
});
```
-### Class Components
-[Vue Class Components](https://class-component.vuejs.org/) offers an alternative class-style syntax for Vue components which integrates well with TypeScript.
-
-To have consistent support for decorators in your Vue components, it's also recommended to install [vue-property-decorator](https://github.com/kaorun343/vue-property-decorator).
-
-
-To get started with both libraries in your existing Vue project, run:
-```
-npm install vue-class-component vue-property-decorator
-```
-
-You only need to import `vue-property-decorator` into your `.vue` file as it extends `vue-class-component`.
-
-You can now write TS in your components like this:
-
-```vue
-
-
- {{ count }}
-
-
- {{ computedValue }}
-
-
-
-
-```
-See the [full guide for Vue Class Components](https://class-component.vuejs.org/guide/class-component.html#data).
-
-> _Class components should not confused with the now abandoned [Class API proposal](https://github.com/vuejs/rfcs/pull/17#issuecomment-494242121)._
-
## Props
`PropType` can be used to annotate props with a particular object shape.
@@ -176,11 +117,13 @@ export default Vue.extend({
```
-With vue-class-components and vue-property-decorator, you can use the `Prop` decorator:
+Alternatively, you can also annote your prop types with an anonymous function:
```vue
+import Vue from 'vue'
+
```
-## Data Properties
+## Data Properties (Options API)
You can enforce types on Vue data properties by annotating the return data object:
@@ -242,6 +191,31 @@ export default Vue.extend({
```
Note that [type assertion](https://www.typescriptlang.org/docs/handbook/basic-types.html#type-assertions) like this does not provide any type safety. If for example, the `contents` property was missing in `newPost`, TypeScript would not catch this error.
+## Computed Properties (Options API)
+
+Typing the return type for your computed properties is important especially when `this` is involved as TypeScript sometimes has trouble infering the type.
+
+```ts
+
+export default Vue.extend({
+ data() {
+ return {
+ name: 'World',
+ }
+ },
+ computed: {
+ greet(): string { //👈 Remember to annotate your computed properties like so.
+ return 'Hello ' + this.name
+ },
+ }
+})
+
+```
+
+>
+
+
# Other Vue + TypeScript resources
- Views on Vue podcast - https://devchat.tv/views-on-vue/vov-076-typescript-tell-all-with-jack-koppa/
- Focuses a lot on class components and vue-property-decorator - https://blog.logrocket.com/how-to-write-a-vue-js-app-completely-in-typescript/
+- Vue 3 Hooks and Type Safety with TypeScript - https://www.youtube.com/watch?v=aJdi-uEKYAc
diff --git a/class-components.md b/class-components.md
new file mode 100644
index 0000000..4e403c3
--- /dev/null
+++ b/class-components.md
@@ -0,0 +1,108 @@
+# Class Components
+
+## Overview
+
+[Vue Class Components](https://class-component.vuejs.org/) offers an alternative class-style syntax for Vue components which integrates well with TypeScript.
+
+To have consistent support for decorators in your Vue components, it's also recommended to install [vue-property-decorator](https://github.com/kaorun343/vue-property-decorator).
+
+
+To get started with both libraries in your existing Vue project, run:
+```
+npm install vue-class-component vue-property-decorator
+```
+
+You only need to import `vue-property-decorator` into your `.vue` file as it extends `vue-class-component`.
+
+You can now write TS in your components like this:
+
+```vue
+
+
+ {{ count }}
+
+
+ {{ computedValue }}
+
+
+
+
+```
+See the [full guide for Vue Class Components](https://class-component.vuejs.org/guide/class-component.html#data).
+
+> _Class components should not confused with the now abandoned [Class API proposal](https://github.com/vuejs/rfcs/pull/17#issuecomment-494242121)._
+
+## Props
+You can use the `Prop` decorator to annoate your prop types like so:
+
+```ts
+
+```
+Is equivalent to:
+
+```ts
+import Vue from "vue-property-decorator";
+import Vue, { PropType } from 'vue'
+
+interface PersonInfo {
+ firstName: string,
+ surname: string,
+ age: number
+}
+export default {
+ props: {
+ info: {
+ type: Object as PropType,
+ required: true
+ },
+ admin: {
+ type: Boolean,
+ default: false
+ }
+ },
+}
+
+```
\ No newline at end of file
diff --git a/vue-3.md b/vue-3.md
index 62b93bb..5192996 100644
--- a/vue-3.md
+++ b/vue-3.md
@@ -30,3 +30,46 @@ declare const props: {
export const welcome = computed(() => `Welcome, ${props.name}!`)
```
+
+## Composition API
+
+### Refs
+
+Vue can infer the type of your `ref`'s but if you need to represent some more complex types you can do so with generics:
+
+```ts
+import {ref} from "vue"
+
+interface PersonInfo {
+ firstName: string,
+ surname: string,
+ age: number
+}
+
+const people = ref([])
+
+```
+
+Alternatively you can use casting with `as`. This should be used if the type is unknown. Consider this example where we create a composition wrapper function around `fetch` and we dont know the data structure that will be returned.
+
+```ts
+
+import { ref, Ref } from "vue";
+
+type ApiRequest = () => Promise;
+
+// When using this function we can supply the type via generics
+export function useAPI(url: RequestInfo, options?: RequestInit) {
+
+ const response = ref() as Ref; // 👈 note we're typing our ref using `as`
+
+ const request: ApiRequest = async () => {
+ const resp = await fetch(url, options);
+ const data = await resp.json();
+ response.value = data;
+ };
+
+ return { response, request };
+}
+
+```
\ No newline at end of file