How to manually define props type in vue3 with typescript

Viewed 8960

I can do

defineComponent({
  props: {
    name: { type: String as PropType<string> }
  }
})

to tell vue3 that my props type is { name: string }, but if I have several component have the same props type, how can I share the defination?

If I define props in :

const props = {
  name: String as PropType<string>
}

then use it like this:

defineComponent({
  props: props,
})

It won't work, the type I got in setup function of props is not right.

3 Answers

this answer is purely addition to @Xinchao's answer.

one way is to destructure common props like following:

// taken from @Xinchao's answer 
const commonProps = {
  name: { type: String as PropType<string> }
}

defineComponent({
  props:{
    ...commonProps,

    extra: { }

  }
})

another way is to write function which returns specific object like following

function getStringProp(required=false) {
    return {
       type: String as PropType<string>,
       required,
       default: '',
    };
}


defineComponent({
  props:{
    name: getStringProp(true),
    nickName: getStringProp(),
    extra: { }

  }
})

this case specifically come handy where prop is Array or Object; where we can cast the type like following

function getArrayProp<T>(required=false) {
    return {
       type: Array as PropType<T[]>,
       required,
       default: () => [],
    };
}


defineComponent({
  props:{
    options: getArrayProp<Options>(true),
    stringOptions: getArrayProp<string>(true),
  }
})

The props options provided for defineComponent is a plain js object solely for type annotation purpose, so you can employ whatever technics in javascript for sharing structures between objects:

// in common.ts
export const commonProps = {
  name: { type: String as PropType<string> }
}

// in your component.vue
import commonProps from "./common.ts";

defineComponent({
  props:{
    ...commonProps,

    extra: { }

  }
})

If you're using the composition API with Vue 2 in preparation for switching to Vue 3, you have to use the PropType from that package instead of the vue package.

// Wrong for Vue 2
import Vue, { PropType } from 'vue'
import { defineComponent } from '@vue/composition-api'

// Right for Vue 2
import { defineComponent, PropType } from '@vue/composition-api'
Related