oxc-project/oxc · error · OxcDiagnostic
`defineOptions()` cannot accept type arguments.
Error message
`defineOptions()` cannot accept type arguments.
What it means
Diagnostic from the oxlint rule `vue/valid-define-options`. In `check_call`, if `call.type_arguments` is present the rule reports that `defineOptions()` cannot accept type arguments. Unlike `defineProps`/`defineEmits`, `defineOptions` has no type-parameter form in the Vue compiler — passing `defineOptions<{...}>()` is a compile error because the compiler macro signature only takes a runtime object literal.
Source
Thrown at crates/oxc_linter/src/rules/vue/valid_define_options.rs:36
}
fn multiple_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("`defineOptions` has been called multiple times.").with_label(span)
}
fn not_defined_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("Options are not defined.").with_label(span)
}
fn disallow_prop_diagnostic(span: Span, prop_name: &str, instead_macro: &str) -> OxcDiagnostic {
OxcDiagnostic::warn(format!(
"`defineOptions()` cannot be used to declare `{prop_name}`. Use `{instead_macro}()` instead."
))
.with_label(span)
}
fn type_args_diagnostic(span: Span) -> OxcDiagnostic {
OxcDiagnostic::warn("`defineOptions()` cannot accept type arguments.").with_label(span)
}
#[derive(Debug, Default, Clone)]
pub struct ValidDefineOptions;
declare_oxc_lint!(
/// ### What it does
///
/// Enforce valid use of the `defineOptions` compiler macro.
///
/// ### Why is this bad?
///
/// `defineOptions` is a compiler macro for `<script setup>`. It must be called
/// with a single object literal containing component options that are evaluable
/// at compile time. Misuse such as referencing locally declared variables,
/// declaring `props`/`emits`/`expose`/`slots`, calling without arguments, or
/// passing type arguments cannot be processed by the compiler.
///View on GitHub (pinned to e1e7af627c)
Solutions
- Remove the type argument list and pass the options as a runtime object literal: `defineOptions({ name: 'Foo' })`.
- If you wanted typed props, switch to `defineProps<{ msg?: string }>()` instead of `defineOptions`.
- If you need the object typed, annotate a separate const in a sibling `<script>` block or cast values (`as`) inside the object literal.
Example fix
// before
<script setup lang="ts">
defineOptions<{ name: 'Foo' }>()
</script>
// after
<script setup lang="ts">
defineOptions({ name: 'Foo' })
</script> Defensive patterns
Strategy: validation
Validate before calling
if (/\bdefineOptions\s*</.test(src)) {
throw new Error('defineOptions cannot take type arguments — pass a runtime object literal');
} Prevention
- Remember only defineProps/defineEmits (and withDefaults) have type-parameter forms; defineOptions does not.
- Enable vue/valid-define-options in the editor so the mistake is flagged as you type.
When it happens
Trigger: A .vue file (VueSetup) containing `defineOptions<SomeType>()` — i.e. the call has a `<...>` type argument list, regardless of whether a runtime argument follows. Typical case: `<script setup lang="ts"> defineOptions<{ name: 'Foo' }>() </script>`. The diagnostic span is the type-arguments span.
Common situations: Developers who know `defineProps<T>()`/`defineEmits<T>()` assume `defineOptions<T>()` follows the same pattern; IDE autocomplete inserting type parameters; porting type-driven code from `defineProps` style.
Related errors
- `defineOptions` is referencing locally declared variables.
- `defineOptions` has been called multiple times.
- Options are not defined.
- `defineOptions()` cannot be used to declare `{prop_name}`. U
- `defineProps` has both a type-only emit and an argument.
AI-assisted analysis of oxc-project/oxc@e1e7af627c (2026-08-20).
Data as JSON: /api/errors/ae2520395e13dac0.
Report an issue: GitHub.