Vue-next: How to properly type props in TS

Created on 3 Jul 2020  Â·  1Comment  Â·  Source: vuejs/vue-next

Version

3.0.0-beta.18

Reproduction link

https://github.com/whu-luojian/webpack-vue3

Steps to reproduce

<script lang="ts">
import { defineComponent, ref } from 'vue'

type TodoItem = {
  id: number
  text: string
  completed: boolean
}

type Props = {
  todo: TodoItem
}

export default defineComponent({
  name: 'TodoItem',
  props: {
    todo: {
      type: Object,
      required: true
    }
  },
  setup(props: Props) {
    console.log(JSON.stringify(props, null, 2))
    const count = ref(0)
    return {
      count
    }
  }
})
</script>

What is expected?

it will work correctly or there are any better solution to properly type props in TS

What is actually happening?

setup function throw a ts error by Vetur:
No overload matches this call.
The last overload gave the following error.
Type '(this: void, props: Props) => { count: Ref; }' is not assignable to type '(this: void, props: Readonly<{ todo: { [key: string]: any; }; } & {}>, ctx: SetupContext>) => void | RenderFunction | { ...; }'.
Types of parameters 'props' and 'props' are incompatible.
Type 'Readonly<{ todo: { [key: string]: any; }; } & {}>' is not assignable to type 'Props'.
Types of property 'todo' are incompatible.
Type '{ [key: string]: any; }' is missing the following properties from type 'TodoItem': id, text, completedVetur(2769)


Related issues:
https://github.com/vuejs/vue-next/issues/1155
https://github.com/vuejs/vue-next/issues/1114

Most helpful comment

Just use the PropType, and remove type annotation on setup(props: Props):

export default defineComponent({
  name: 'TodoItem',
  props: {
    todo: {
      type: Object as PropType<TodoItem>,
      required: true
    }
  },
  setup(props) {
    console.log(JSON.stringify(props, null, 2))
    const count = ref(0)
    return {
      count
    }
  }
})

>All comments

Just use the PropType, and remove type annotation on setup(props: Props):

export default defineComponent({
  name: 'TodoItem',
  props: {
    todo: {
      type: Object as PropType<TodoItem>,
      required: true
    }
  },
  setup(props) {
    console.log(JSON.stringify(props, null, 2))
    const count = ref(0)
    return {
      count
    }
  }
})
Was this page helpful?
0 / 5 - 0 ratings

Related issues

Jexordexan picture Jexordexan  Â·  4Comments

jods4 picture jods4  Â·  4Comments

NMFES picture NMFES  Â·  3Comments

HakamFostok picture HakamFostok  Â·  3Comments

sarangnx picture sarangnx  Â·  3Comments