simolus3 / drift

Drift is an easy to use, reactive, typesafe persistence library for Dart & Flutter.
https://drift.simonbinder.eu/
MIT License
2.66k stars 372 forks source link

Cannot read single nullable column when type converter is used #3350

Closed JetA2 closed 1 day ago

JetA2 commented 1 day ago

I'm having issues reading a single nullable column that uses a type converter.

To reproduce, I've copied the Preferences code from the documentation on type converters.

When I try to create a function to read the preferences column, the linter complains:

The argument type 'GeneratedColumnWithTypeConverter<Preferences?, String>' can't be assigned to
the parameter type 'GeneratedColumnWithTypeConverter<Preferences, String>'.
dart(argument_type_not_assignable)

The readWithConverter function does not seem to support a nullable value. When I read the whole row, it works fine.

Non-functioning code:

Future<Preferences?> preferences(String actor) async {
    final result = await (selectOnly(account)
          ..addColumns([account.preferences])
          ..where(account.actor.equals(actor)))
        .getSingle();

    return result.readWithConverter(account.preferences);
             Linter complains here: ^^^^^^^^^^^^^^^^^^^
}

Functioning code:

Future<Preferences?> preferences(String actor) async {
    final result =
        await managers.account.filter((f) => f.actor(actor)).getSingle();

    return result.preferences;
}

Table:

class Account extends Table {
  @override
  Set<Column> get primaryKey => {actor};

  TextColumn get actor => text()(); // Actor did

  TextColumn get preferences =>
      text().map(const PreferenceConverter()).nullable()();
}

Am I doing something wrong or is this not supported?

simolus3 commented 1 day ago

Type inference can be weird, this works:

    final preferences = result.readWithConverter(users.preferences);
    return preferences;

And this works too:

    return result.readWithConverter<Preferences?, String>(users.preferences);

I'm not fully sure why inference fails for the original call, but we can't really relax the type of readWithConverter without introducing other issues. So I'm afraid you'd probably have to use one of the workarounds.