diff --git a/README.md b/README.md
index 7350906..0d7ea93 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,9 @@
# Vue+TypeScript Cheatsheets
-Cheatsheets for experienced Vue developers getting started with TypeScript
+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,6 +88,134 @@ const Component = defineComponent({
});
```
-# Other Vue + TypeScript resources
+## Props
+
+`PropType` can be used to annotate props with a particular object shape.
+
+```vue
+import Vue, { PropType } from 'vue'
+
+
+```
+
+Alternatively, you can also annote your prop types with an anonymous function:
+
+```vue
+import Vue from 'vue'
+
+
+```
+
+## Data Properties (Options API)
+
+You can enforce types on Vue data properties by annotating the return data object:
+
+```ts
+interface Post {
+ title: string;
+ contents: string;
+ likes: number;
+}
+
+export default Vue.extend({
+ data(): { newPost: Post } {
+ return {
+ newPost: {
+ title: "",
+ contents: "",
+ likes: 0
+ }
+ };
+ }
+});
+```
+
+It might be tempting to annotate your Vue data properties using `as` like this:
+
+```ts
+interface Post {
+ title: string;
+ contents: string;
+ likes: number;
+}
+
+export default Vue.extend({
+ data() {
+ return {
+ newPost: {
+ title: "",
+ contents: "",
+ likes: 0
+ } as Post // ❌ Avoid doing this
+ };
+ }
+});
+```
+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)
-- Views on Vue podcast - https://devchat.tv/views-on-vue/vov-076-typescript-tell-all-with-jack-koppa/
+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