Strongly typing props of vue components using composition api and typescript typing system
Asked Answered
C

2

35

I am using vue composition api with typescript.

How can I strongly type the component props using typescript typing system?

Canady answered 29/1, 2020 at 11:43 Comment(0)
W
6

As explained in the official docs you can type props in two ways:

Define arops via argument annotation

import { defineComponent } from 'vue'

export default defineComponent((props: { foo: string }) => {
  props.foo
})

Or like this

import { defineComponent } from 'vue'

export default defineComponent({
  props: {
    foo: String
  },
  setup(props) {
    props.foo // <- type: string
  }
})
Wispy answered 29/1, 2020 at 15:37 Comment(0)
T
63

Troy Kessier's answer is not entirely accurate. I quote the documentation on definecomponent:

Alternatively if your component does not use any option other than setup itself, you can pass the function directly […]

So there are not two ways of declaring properties, but rather two ways of declaring a component, and each of them provides its own way of typing props.

With the classic way and TypeScript, use PropType:

import { defineComponent, PropType } from 'vue'

export default defineComponent({
  props: {
    someOptionalString: String,

    someRequiredString: {
      type: String,
      required: true
    },

    someObject: {
      type: Object as PropType<MyObjectType>,
      required: true
    },
  },

  // …
})

Notice: PropType helps to give a correct TypeScript type to the props parameter in the setup function. But the underlying Vue type for the props remains Object and there is currently no way to enforce a better typing for these props passed by the parent component.

Thrush answered 8/2, 2020 at 13:53 Comment(5)
I tried this and it did not work for me, if I pass in { foo: 'bar' } it doesn't complain, in other words it's only checking if the parent component is passing an object, not if it matches the data structure of my custom type. I'm using lang="ts" in the .vue script tag, and TypeScript is working properly in .ts files, and I've got types working nicely in Vuex.Chaussure
@LeeComstock Of course. I edited. Let me know if it's clear now.Thrush
Those are not Typescript typings.Portwin
> there is no way to enforce better typing for these props — I think there is. You can define a schema using zod and add a validator for every prop. Just make a utility function and it’ll be rather straight-forward to use. This doesn’t enforce it at compile-time, but that’s unfortunately a fundamental limit of vue’s non-standard "amazing" template syntax...Cyndy
Also, please note that when using vue2 + @vue/composition-api, the PropType should instead be imported from that package, not from vue itself. Otherwise, at least for me, it’ll error everywhere.Cyndy
W
6

As explained in the official docs you can type props in two ways:

Define arops via argument annotation

import { defineComponent } from 'vue'

export default defineComponent((props: { foo: string }) => {
  props.foo
})

Or like this

import { defineComponent } from 'vue'

export default defineComponent({
  props: {
    foo: String
  },
  setup(props) {
    props.foo // <- type: string
  }
})
Wispy answered 29/1, 2020 at 15:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.