35

I am using vue composition api with typescript.

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

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

5 Comments

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.
@LeeComstock Of course. I edited. Let me know if it's clear now.
Those are not Typescript typings.
> 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...
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.
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
  }
})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.