Skip to content

Instantly share code, notes, and snippets.

@lbssousa
Last active July 13, 2022 11:32
Show Gist options
  • Save lbssousa/fc74c39e4aa22a85316a0ed1fc26fa05 to your computer and use it in GitHub Desktop.
Save lbssousa/fc74c39e4aa22a85316a0ed1fc26fa05 to your computer and use it in GitHub Desktop.
A little cheatsheet of how to write type-safe Vue single file components, using either TypeScript or JSDoc comments (reference: https://blog.usejournal.com/type-vue-without-typescript-b2b49210f0b)
<template>
<div>
<slot/>
</div>
</template>
<script>
// @ts-check
/**
* @typedef {Object} SampleObjectProp
* @property {number} key1 // mandatory
* @property {string} [key2] // optional
*/
/**
* @typedef {Object} MyComponentData
* @property {boolean} data1
* @property {number} data2
* @property {string} data3
*/
export default {
name: 'MyComponent',
props: {
prop1: Boolean,
prop2: {
type: Number,
default: 10
},
prop3: {
type: String,
default: 'foo'
},
prop4: {
/** @type {import('vue').PropType<string[]>} */
type: Array,
default: () => []
},
prop5: {
/** @type {import('vue').PropType<SampleObjectProp>} */
type: Object,
default: () =>
/** @type {SampleObjectProp} */
({ key1: 0 })
}
},
/** @type {() => MyComponentData} */
data () {
return {
data1: true,
data2: 0,
data3: ''
}
},
computed: {
/** @returns {number} */
myDouble () {
return 2 * this.data2
},
/** @returns {string} */
myHello () {
return `Hello, ${this.data3}!`
}
},
methods: {
/** @param {boolean} value */
setData1 (value) {
this.data1 = value
},
/** @param {number} value */
setData2 (value) {
this.data2 = value
},
/** @param {string} value */
setData3 (value) {
this.data3 = value
},
/** @param {string} name */
greet (name) {
return `${this.myHello} How are you, ${name}?`
}
}
}
</script>
<style>
</style>
<template>
<div>
<slot/>
</div>
</template>
<script lang="ts">
import Vue, { PropType } from 'vue'
interface SampleObjectProp {
key1: number // mandatory
key2?: string // optional
}
interface MyComponentData {
data1: boolean
data2: number
data3: string
}
export default Vue.extend({
name: 'MyComponent',
props: {
prop1: Boolean,
prop2: {
type: Number,
default: 10
},
prop3: {
type: String,
default: 'foo'
},
prop4: {
type: Array as PropType<string[]>,
default: (): string[] => []
},
prop5: {
type: Object as PropType<SampleObjectProp>,
default: (): SampleObjectProp => ({ key1: 0 })
}
},
data (): MyComponentData {
return {
data1: true,
data2: 0,
data3: ''
}
},
computed: {
myDouble (): number {
return 2 * this.data2
},
myHello (): string {
return `Hello, ${this.data3}!`
}
},
methods: {
setData1 (value: boolean) {
this.data1 = value
},
setData2 (value: number) {
this.data2 = value
},
setData3 (value: string) {
this.data3 = value
},
greet (name: string) {
return `${this.myHello} How are you, ${name}?`
}
}
})
</script>
<style>
</style>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment