oxc-project/oxc · error · OxcDiagnostic
`defineProps` has both a type-only emit and an argument.
Error message
`defineProps` has both a type-only emit and an argument.
What it means
Diagnostic from the oxlint rule `vue/valid-define-props` (crates/oxc_linter/src/rules/vue/valid_define_props.rs). The rule delegates each `defineProps` call to the shared helper `check_define_macro_call_expression`; when the call has BOTH a literal type parameter (type-only declaration) and a runtime argument, the helper returns `DefineMacroProblem::HasTypeAndArguments`. Passing both makes the runtime argument win and silently discards the type-only declaration, degrading type inference.
Source
Thrown at crates/oxc_linter/src/rules/vue/valid_define_props.rs:14
use oxc_ast::AstKind;
use oxc_diagnostics::OxcDiagnostic;
use oxc_macros::declare_oxc_lint;
use oxc_span::Span;
use crate::{
context::LintContext,
frameworks::FrameworkOptions,
rule::Rule,
utils::{DefineMacroProblem, check_define_macro_call_expression, has_default_exports_property},
};
fn has_type_and_arguments_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("`defineProps` has both a type-only emit and an argument.")
.with_help("remove the argument for better type inference.")
.with_label(span)
}
fn called_multiple_times(span: Span, second_span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("`defineProps` has been called multiple times.")
.with_help("combine all `defineProps` calls into a single `defineProps` call.")
.with_labels([
span.label("`defineProps` is called here"),
second_span.label("`defineProps` is called here too"),
])
}
fn events_not_defined(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Props are not defined.")
.with_help("Define at least one prop in `defineProps`.")
.with_label(span)
}View on GitHub (pinned to e1e7af627c)
Solutions
- Delete the runtime argument and keep the type-only form: `defineProps<{ msg?: string }>()`.
- If you need prop defaults with types, use `withDefaults(defineProps<{ msg?: string }>(), { msg: 'hi' })` instead of a second argument.
- If the runtime object is the source of truth, drop the type parameter instead: `defineProps({ msg: String })`.
Example fix
// before
<script setup lang="ts">
defineProps<{ msg?: string }>({ msg: String })
</script>
// after
<script setup lang="ts">
defineProps<{ msg?: string }>()
</script> Defensive patterns
Strategy: validation
Validate before calling
if (/\bdefineProps\s*<[^>]*>\s*\(\s*\S/.test(src)) {
throw new Error('defineProps has both a type parameter and a runtime argument — remove one');
} Prevention
- Pick one declaration style per component: type-only or runtime object, never both.
- Use withDefaults(defineProps<T>(), {...}) for defaults instead of adding a second argument.
When it happens
Trigger: A `defineProps` call (VueSetup framework option) shaped like `defineProps<{ msg?: string }>({ msg: String })` — i.e. `call.type_arguments` present AND at least one runtime argument. Reported on the whole call span with help 'remove the argument for better type inference.'
Common situations: Migrating a runtime-props component to type-based props and forgetting to delete the old object argument; merging tutorial snippets that use both styles; refactors where a defaults object was pasted next to a newly added type parameter.
Related errors
- Use type-based declaration instead of runtime declaration
- `defineOptions()` cannot be used to declare `{prop_name}`. U
- `defineOptions()` cannot accept type arguments.
- `defineProps` has been called multiple times.
- Props are not defined.
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/62487c3d7522e61e.
Report an issue: GitHub.