{"record":{"id":"5e3b6e35dcc59344","repo":"oxc-project/oxc","slug":"prefer-destructuring-from-defineprops-directly","errorCode":null,"errorMessage":"Prefer destructuring from `defineProps` directly.","messagePattern":"Prefer destructuring from `defineProps` directly\\.","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"info","filePath":"crates/oxc_linter/src/rules/vue/define_props_destructuring.rs","lineNumber":16,"sourceCode":"use oxc_ast::{AstKind, ast::BindingPattern};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_span::Span;\nuse schemars::JsonSchema;\nuse serde::{Deserialize, Serialize};\n\nuse crate::{\n    AstNode,\n    context::{ContextHost, LintContext},\n    frameworks::FrameworkOptions,\n    rule::{DefaultRuleConfig, Rule},\n};\n\nfn prefer_destructuring_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Prefer destructuring from `defineProps` directly.\").with_label(span)\n}\n\nfn avoid_destructuring_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Avoid destructuring from `defineProps`.\").with_label(span)\n}\n\nfn avoid_with_defaults_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Avoid using `withDefaults` with destructuring.\").with_label(span)\n}\n\n#[derive(Debug, Default, Clone, Eq, PartialEq, Serialize, Deserialize, JsonSchema)]\n#[serde(rename_all = \"kebab-case\")]\nenum Destructure {\n    /// Requires destructuring when `defineProps` is assigned to a variable and warns against using `withDefaults` with destructuring\n    #[default]\n    OnlyWhenAssigned,\n    /// Requires destructuring when using `defineProps` and warns against using `withDefaults` with destructuring\n    Always,","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/vue/define_props_destructuring.rs#L1-L34","documentation":"Diagnostic from oxlint's vue/define-props-destructuring rule (style category, since oxlint 1.20.0). It fires when the result of defineProps() is stored in a variable instead of being destructured, under the \"only-when-assigned\" (default) or \"always\" option. The rule pushes the modern Vue 3.5+ pattern where destructured props keep reactivity via compiler transforms.","triggerScenarios":"A file contains `const props = defineProps(['foo'])` or `const props = defineProps<{ foo?: string }>()` (any call with arguments/type args whose result is assigned) while the rule's `destructure` option is \"only-when-assigned\" or \"always\". The rule matches defineProps calls with at least one argument or type parameter.","commonSituations":"Adopting the newer destructuring convention after upgrading to Vue 3.5+, or inheriting a config tuned for it; older components using `props.foo` everywhere then get flagged during CI.","solutions":["Destructure at the call site: const { foo } = defineProps(['foo'])","Use default values in the destructure (Vue 3.5+): const { bar = 'default' } = defineProps<{ bar?: string }>()","If the codebase intentionally uses props.xxx, set the option to { \"destructure\": \"never\" }","Disable the rule for transitional files with an oxlint-disable comment"],"exampleFix":"// before\nconst props = defineProps(['foo'])\nconsole.log(props.foo)\n// after\nconst { foo } = defineProps(['foo'])\nconsole.log(foo)","handlingStrategy":"validation","validationCode":"# find non-destructured assignments before enabling the rule\ngrep -rnE \"const +[A-Za-z$_][A-Za-z0-9$_]* *= *defineProps\" --include='*.vue' src","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only enable destructuring-enforcing modes on Vue 3.5+ where the compiler keeps destructured props reactive","Pair the rule with a repository-wide codemod so all defineProps call sites change in one pass"],"tags":["vue","oxlint","lint","script-setup","defineprops","destructuring","style"],"backgroundTag":"vue-defineprops-destructuring","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}