In Dart, what does the required modifier on a named parameter guarantee, and how does it interact with nullability and default values?
answer
- named but not optional
- caller must pass it
- independent of nullability
- no default alongside required
- @required annotation is history
basics
~20 srequired makes a named parameter mandatory: a call that omits it is a compile error. It is independent of nullability, so required int? is legal and callers must pass null explicitly, but a required parameter cannot also have a default value.
solid answer
~40 sNamed parameters are optional by default, and under null safety an optional parameter must either be nullable or have a default, because an omitted argument would otherwise be `null`. `required` fills the missing corner: a parameter that is **named but mandatory**. Omitting it is a compile error (`missing_required_argument`), so a non-nullable named parameter needs no default. `required` and nullability are separate: `required Widget? child` forces the caller to decide, even if the decision is `null`. A default value is pointless on a required parameter and is rejected (`default_value_on_required_parameter`). Before null safety, the `@required` annotation from `package:meta` was only an analyzer hint; the Dart 3.10 analyzer removed support for it, so the keyword is the only form.
code
dart · 14 linesclass Greeting {
const Greeting({required this.name, required this.title, this.suffix = '!'});
final String name;
final String? title; // required, but may be null
final String suffix;
String render() => '${title ?? ''} $name$suffix'.trim();
}
void main() {
print(const Greeting(name: 'Ada', title: null).render()); // Ada!
print(const Greeting(name: 'Ada', title: 'Dr').render()); // Dr Ada!
}go deeper
Recall that required forces callers to pass a named argument and that omitting it fails at compile time.
Explain why optional parameters must be nullable or defaulted under null safety, and why required and ? answer different questions.
Design constructors so that missing inputs are compile errors, choosing between required T, required T?, and a default deliberately.
Set API conventions for public packages: which parameters are required, which defaulted, and how adding a required parameter breaks every caller.
## The gap `required` fills Dart has **positional** and **named** parameters, and each can be **mandatory** or **optional**. Before null safety, three of the four combinations had syntax; named-and-mandatory did not: | | mandatory | optional | |---|---|---| | positional | `f(int x)` | `f([int? x])` | | named | `f({required int x})` | `f({int? x})` or `f({int x = 0})` | With null safety an omitted optional argument would silently be `null`, so an optional parameter must be **nullable or have a default value**. That left no way to declare a named, non-nullable parameter without a default — until `required` arrived with null safety and filled the corner. ## What `required` guarantees - Every call **must pass the argument by name**; omitting it is a compile error reported as `missing_required_argument`. - Because the caller always supplies a value, a **non-nullable** type needs no default: `{required String name}` is complete. - The guarantee is **static**. Nothing is checked at runtime, and there is no way to call the function without the argument in sound code. ```dart void connect({required String host, int port = 443, String? proxy}) {} void main() { connect(host: 'example.test'); // ok connect(host: 'example.test', port: 8443); // ok // connect(port: 80); // error: missing_required_argument } ``` ## Required-ness is independent of nullability It is easy to conflate the two, but they answer different questions: 1. **Must the caller mention this parameter?** — `required` answers that. 2. **May the value be absent?** — the `?` in the type answers that. So all combinations are legal and mean different things: - `{required int x}` — caller must pass a real `int`. - `{required int? x}` — caller must pass something, possibly an explicit `null`. Useful when forgetting the argument is a bug but `null` is a meaningful choice. - `{int x = 0}` — caller may omit it and gets `0`. - `{int? x}` — caller may omit it and gets `null`. The Dart language tour illustrates this with a Flutter widget constructor, `const Scrollbar({super.key, required Widget child})`, and notes that `required Widget? child` is also valid. ## What is rejected - **`required` with a default value** — `{required String message = 'x'}` is an error (`default_value_on_required_parameter`); the default could never be used. - **`required` on a positional parameter** — positional parameters are already mandatory unless placed in `[]`, and the modifier only applies inside `{}`. ## History: the `@required` annotation Before null safety, Flutter code marked mandatory named parameters with the **`@required` annotation** from `package:meta`. It was only a hint: the analyzer warned, but a caller could still omit the argument and receive `null`. With null safety the **keyword** replaced it, and the Dart 3.10 analyzer **removed support** for the deprecated annotation. Code that still uses `@required` should switch to the keyword. ## Design guidance - Prefer `required` over a nullable parameter plus a runtime `ArgumentError` check: the compiler then enforces the contract at every call site. - Use `required T?` sparingly, when a caller must consciously choose absence. - Keep constructors of widgets and value objects explicit: `required this.title` makes a missing field a compile error rather than a bug found at runtime. - Since Dart 3.12, a named initializing formal may target a private field, so `Point({required this._x})` is legal and callers still write `Point(x: 1)`.
- In Dart, when would you declare a parameter as `required T?` rather than `T?`?When omitting the argument is likely a mistake but `null` is a legitimate value. `required` forces every caller to state a value, so a forgotten argument becomes a compile error, while `T?` still allows an explicit `null`. With plain `T?`, forgetting the argument and choosing `null` look identical.
- In Dart, what happened to the @required annotation from package:meta?It predated null safety and only produced an analyzer hint, so a caller could still omit the argument and pass `null` implicitly. The `required` keyword replaced it with a compile-time guarantee, and the Dart 3.10 analyzer removed support for the old annotation, so code must use the keyword.
saying these in an interview costs you the question
- required makes a parameter non-nullable automatically
- A required named parameter can still have a default value as a fallback
- required is checked at runtime and throws if the argument is missing
- A nullable named parameter can never be marked required
- @required from package:meta is the current way to mark named parameters