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
- Remove `required: true` and keep the `default` (the rule's autofix does exactly this — apply the suggested fix).
- If the prop genuinely must be provided by callers, remove the `default` instead and keep `required: true`.
- Pick one strategy per prop, never both, and document the convention in your team's style guide.
- 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
- Adopt one rule: a prop declares either `required: true` or `default`, never both.
- Apply the rule's autofix during review instead of leaving contradictions in place.
- Let TS optionality follow the presence of `default` in defineProps inference.
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
- TS5081
- Props are defined in both `defineProps` and `export default
- Duplicate key '{name}'. May cause name collision in script o
- `VirtualFree` failed during cleanup: {err}
- Insufficient memory to create fixed-size allocator pool
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/2d0f1d1d2d32a259.
Report an issue: GitHub.