oxc-project/oxc · warning · OxcDiagnostic

Prop "{prop_name}" should be optional.

Error message

Prop "{prop_name}" should be optional.

What it means

The vue/no-required-prop-with-default rule reports a prop declared with both `required: true` and a `default`. In Vue, a prop with a default is always resolved to a value, so it can never be missing; marking it required is contradictory. It also skews TypeScript/`defineProps` inference, which derives optionality from whether `default` exists. The rule has a fixer (RuleFix/RuleFixer are imported) and its help suggests removing the `required: true` option or dropping the `required` key entirely. It checks both Options-API prop objects (find_property) and `defineProps` type signatures via for_each_define_props_type_signature.

Source

Thrown at crates/oxc_linter/src/rules/vue/no_required_prop_with_default.rs:27

    },
};
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_semantic::NodeId;
use oxc_span::{GetSpan, Span};

use crate::{
    AstNode,
    context::LintContext,
    fixer::{RuleFix, RuleFixer},
    frameworks::FrameworkOptions,
    rule::Rule,
    utils::{find_property, for_each_define_props_type_signature},
};

fn no_required_prop_with_default_diagnostic(span: Span, prop_name: &str) -> OxcDiagnostic {
    let msg = format!("Prop \"{prop_name}\" should be optional.");
    OxcDiagnostic::warn(msg)
        .with_help("Remove the `required: true` option, or drop the `required` key entirely to make this prop optional.")
        .with_label(span)
}

#[derive(Debug, Default, Clone)]
pub struct NoRequiredPropWithDefault;

declare_oxc_lint!(
    /// ### What it does
    ///
    /// Enforce props with default values to be optional.
    ///
    /// ### Why is this bad?
    ///
    /// If a prop is declared with a default value, whether it is required or not,
    /// we can always skip it in actual use. In that situation, the default value would be applied.
    /// So, a required prop with a default value is essentially the same as an optional prop.
    ///

View on GitHub (pinned to e1e7af627c)

Solutions

  1. Remove `required: true` and keep the `default` (the rule's autofix does exactly this — apply the suggested fix).
  2. If the prop genuinely must be provided by callers, remove the `default` instead and keep `required: true`.
  3. Pick one strategy per prop, never both, and document the convention in your team's style guide.
  4. Re-run oxlint to confirm the prop passes.

Example fix

// before
props: {
  variant: {
    type: String,
    required: true,   // contradicts the default
    default: 'primary'
  }
}

// after
props: {
  variant: {
    type: String,
    default: 'primary'
  }
}
Defensive patterns

Strategy: validation

Validate before calling

// pre-check a prop definition before shipping it
function assertValidProp(prop) {
  if (prop.required && 'default' in prop) {
    throw new Error(`prop cannot be both required and have a default`);
  }
}

Prevention

When it happens

Trigger: Declaring `{ type: String, required: true, default: 'x' }` in a component's `props`, or a runtime prop object inside `defineProps({ ... })`, where both `required` and `default` keys are present.

Common situations: Adding a default later without removing `required`; teams enforcing 'all props explicit' by marking everything required; migrating from JS to TS prop definitions and keeping both modifiers.

Related errors


AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20). Data as JSON: /api/errors/2d0f1d1d2d32a259. Report an issue: GitHub.