unsafe_ variance
This type is unsafe: a type parameter occurs in a non-covariant position.
Description
#The analyzer produces this diagnostic when an instance member has a result type which is contravariant or invariant in a type parameter of the enclosing declaration. The result type of a variable is its type, and the result type of a getter or method is its return type. This lint warns against such members because they are likely to cause a failing type check at run time, with no static warning or error at the call site.
Example
#
The following code produces this diagnostic because X occurs
as a parameter type in the type of f, which is a
contravariant occurrence of this type parameter:
class C<X> {
bool Function(X) f;
C(this.f);
}
This is unsafe: If c has static type C<num> and run-time type C<int>
then c.f will throw. Hence, every invocation c.f(a) will also throw,
even in the case where a has a correct type as an argument to c.f.
Common fixes
#
If the linted member is or can be private then you may be able
to enforce that it is never accessed on any other receiver than this.
This is sufficient to ensure that that the run-time type error does not
occur. For example:
class C<X> {
// NB: Ensure manually that `_f` is only accessed on `this`.
// ignore: unsafe_variance
bool Function(X) _f;
C(this._f);
// We can write a forwarding method to allow clients to call `_f`.
bool f(X x) => _f(x);
}
You can eliminate the unsafe variance by using a more general type for the linted member. In this case you may need to check the run-time type and perform a downcast at call sites.
class C<X> {
bool Function(Never) f;
C(this.f);
}
If c has static type C<num> then you may test the type. For example,
c.f is bool Function(num). You may safely call it with an argument of
type num if it has that type.
You can also eliminate the unsafe variance by using a much more general
type like Function, which is essentially the type dynamic
for
functions.
class C<X> {
Function f;
C(this.f);
}
This will make c.f(a) dynamically safe: It will throw if and only if the
argument a does not have the type required by the function. This is
better than the original version because it will not throw because of a
mismatched static type. It only throws when it must throw for soundness
reasons.
Unless stated otherwise, the documentation on this site reflects Dart 3.9.2. Page last updated on 2025-9-1. View source or report an issue.