Repository: vuejs/eslint-plugin-vue

Issue #2051: `vue/require-default-prop` is not compatible with the Composition API and `@typescript-eslint/no-unnecessary-condition`
Created: 2022-12-01T16:59:41Z
Checklist

 I have tried restarting my IDE and the issue persists.
 I have read the FAQ and my problem is not listed.


Tell us about your environment

ESLint version: 8.28.0
eslint-plugin-vue version: 9.8.0
Node version: 16.17.0
Operating System: Manjaro

Please show your full configuration:

/* eslint-env node */
require('@rushstack/eslint-patch/modern-module-resolution');

/** @type {import('eslint').Linter.Config} */
module.exports = {
  root: true,
  extends: [
    'eslint:recommended'
  ],
  overrides: [
    {
      files: ['*.ts', '*.tsx'],
      extends: [
        'eslint:recommended',
        'plugin:@typescript-eslint/strict'
      ],
      parserOptions: {
        project: './tsconfig.json',
        extraFileExtensions: ['.vue']
      }
    },
    {
      files: ['*.vue'],
      extends: [
        'plugin:vue/recommended',
        'eslint:recommended',
        'plugin:@typescript-eslint/strict',
        '@vue/eslint-config-typescript/recommended'
      ],
      parser: "vue-eslint-parser",
      parserOptions: {
        parser: "@typescript-eslint/parser",
        project: './tsconfig.json',
        extraFileExtensions: ['.vue']
      }
    }
  ]
}
What did you do?

src/components/DisplayMessageCorrect.vue:
<template>
  <div>{{ resultingMessage }}</div>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue';

const props = defineProps({
  // Wants `default` or `required` to ease the `vue/require-default-prop warning`. This is not
  // desirable when the property could be `undefined`. Right now this is typed as
  // `string | undefined`.
  message: String
})

const resultingMessage = ref(props.message ?? 'No message today')

watch(() => props.message, () => { resultingMessage.value = props.message ?? 'No message today'})
</script>
src/components/DisplayMessageWrong.vue:
<template>
  <div>{{ resultingMessage }}</div>
</template>

<script setup lang="ts">
import { ref, watch } from 'vue';

const props = defineProps({
  // Added default, to ease the vue/require-default-prop warning. Now this prop is extracted as
  // `string` and now `string | undefined`
  message: { type: String, default: undefined }
})

// With default defined, ESLint will now trigger `@typescript-eslint/no-unnecessary-condition` warning
const resultingMessage = ref(props.message ?? 'No message today')

// With default defined, ESLint will now trigger `@typescript-eslint/no-unnecessary-condition` warning
watch(() => props.message, () => { resultingMessage.value = props.message ?? 'No message today'})
</script>
What did you expect to happen?
vue/require-default-prop is not included in any of the recommended configurations or treats Composition API built components differently.
Since the Composition API actually understands the following PropOption shapes as also allowing undefined to be the value type seen within the component:

String
{ type: String }
{ type: String, required: false }
Adding default or required: true; the only ways to fix the warning from this rule, results in the extracted property type to no longer include undefined, the rule is inappropriate for the Composition API.

What actually happened?
The following code will results in:
src/components/DisplayMessageCorrect.vue
  12:3  warning  Prop 'message' requires default value to be set  vue/require-default-prop

src/components/DisplayMessageWrong.vue
  15:30  warning  Unnecessary conditional, expected left-hand side of `??` operator to be possibly null or undefined  @typescript-eslint/no-unnecessary-condition
  18:61  warning  Unnecessary conditional, expected left-hand side of `??` operator to be possibly null or undefined  @typescript-eslint/no-unnecessary-condition

✖ 3 problems (0 errors, 3 warnings)


Repository to reproduce this issue
https://github.com/6XGate/vue-require-default-prop

Duplicate issue #2475: `vue/require-default-prop` should not trigger when type is `x | undefined` without default value
Created: 2024-06-12T08:45:47Z
What rule do you want to change?
vue/require-default-prop
Does this change cause the rule to produce more or fewer warnings?
Is will provide less warnings if the type is already defined as undefined.
How will the change be implemented? (New option, new default behavior, etc.)?
Could be an option to not throw the error / warning when props is not required and has a undefined type set
Please provide some example code that this change will affect:
const props = withDefaults(
  defineProps<{
    // Is not throwing warning because default is set
    modelValue?: string;
    // Should throw warning because no default is set
    label?: string;
    // Should not throw warning because undefined is allowed
    propertyName?: string | undefined;
  }>(),
  {
    modelValue: 'test',
  },
);
What does the rule currently do for this code?
Throws a warning at the propertyName prop
What will the rule do after it's changed?
Will not complain about the propertyName prop
Additional context
If needed, I can look into it myself but I will need to be pointed to the correct files :)

Closing comment (2024-06-12T08:55:44Z): Related to

#2051
#2376