Subscribe on changes!

[TypeScript] An error occurs when defining the type of props using defineProps

avatar
Aug 26th 2021

Version

3.2.6

Reproduction link

https://github.com/LongJinCen/Vue3-TS-error/tree/master

Steps to reproduce

git clone git@github.com:LongJinCen/Vue3-TS-error.git    
npm i   
npm run build

The following code will report an error

<template>
  <span>
    {{ hintMsg }}
  </span>
  <span>{{ iconName }}</span>
</template>
<script setup lang="ts">
import { ref } from 'vue'
interface Props {
  hintMsg: string;
  iconName: string;
}

withDefaults(defineProps<Props>(), {
  hintMsg: '',
  iconName: 'question'
})

const hint = ref(null)

</script>

If I didn't use the defineProps to define the types, I wouldn't get an error

<template>
  <span>
    {{ hintMsg }}
  </span>
  <span>{{ iconName }}</span>
</template>

<script setup lang="ts">
import { ref } from 'vue'
interface Props {
  hintMsg: string;
  iconName: string;
}

defineProps({
  hintMsg: String,
  iconName: String
})

const hint = ref(null)

</script>

What is expected?

no type error and build sucess

What is actually happening?

there is a type error

[tsl] ERROR in /Users/bytedance/code/webpack5-ts-vue3/src/App.vue.ts(10,3)
      TS2769: No overload matches this call.
  The last overload gave the following error.
    Type 'undefined' is not assignable to type 'Readonly<ComponentPropsOptions<Data>> & ThisType<void>'.
      Type '(this: void, __props: { hintMsg: string; iconName: string; }, { expose }: SetupContext<EmitsOptions>) => { hint: Ref<null>; }' is not assignable to type '(this: void, props: Readonly<LooseRequired<(Readonly<(readonly unknown[] & { [x: number]: string; } & { [iterator]?: IterableIterator<string> | undefined; length?: number | undefined; toString?: string | undefined; toLocaleString?: string | undefined; ... 19 more ...; flat?: unknown[] | undefined; }) | ({ ...; } & ....'.
feat: init
        Types of parameters '__props' and 'props' are incompatible.
          Type 'Readonly<LooseRequired<(Readonly<(readonly unknown[] & { [x: number]: string; } & { [iterator]?: IterableIterator<string> | undefined; length?: number | undefined; toString?: string | undefined; toLocaleString?: string | undefined; ... 19 more ...; flat?: unknown[] | undefined; }) | ({ ...; } & ... 1 more ... & { .....' is missing the following properties from type '{ hintMsg: string; iconName: string; }': hintMsg, iconName

The dependencies versions are as follows

   "devDependencies": {
      "@vue/compiler-sfc": "^3.2.6",
      "html-webpack-plugin": "^5.3.2",
      "ts-loader": "^9.2.4",
      "typescript": "^4.3.5",
      "vue-loader": "^16.4.1",
      "webpack": "^5.46.0"
    },
    "dependencies": {
      "vue": "^3.2.6"
    }
avatar
Aug 26th 2021

Your types are different: the one with the interface make the props required while the one with the js object make them optional:

defineProps({
  hintMsg: { type: String, required: true },
  iconName: String
})

Remember to use the forum or the Discord chat to ask questions!

avatar
Aug 26th 2021

Your types are different: the one with the interface make the props required while the one with the js object make them optional:

defineProps({
  hintMsg: { type: String, required: true },
  iconName: String
})

Remember to use the forum or the Discord chat to ask questions!

thank you,I understand, My problem can be solved by the following changes:

interface Props {
  hintMsg?: string;
  iconName?: string;
}

I just checked the official document, which mentioned as follows, I didn’t pay attention...

In addition, the withDefaults helper provides type checks for the default values, and ensures the returned props type has the optional flags removed for properties that do have default values declared.