Skip to content

Generic type T itself becomes nullable if a variable of type T? has a null value #55320

Open
@kaboc

Description

@kaboc
void main() {
  final fooA = Foo(value1: 10);
  final fooB = Foo(value1: 10, value2: null);
  print('${getType(fooA.value1)}'); // int
  print('${getType(fooB.value1)}'); // int?
}

Type getType<T>(T value) => T;

class Foo<T> {
  final T value1;
  final T? value2;

  Foo({required this.value1, this.value2});
}

T can be nullable, but I want to handle value1 as non-nullable when its value is not null. On the other hand, value2 is of type T? because it is a property that often has no value, and also because I intend to prevent T itself from becoming nullable when value2 is null but value1 is not null.

I've noticed that below works as intended.

void main() {
  final bar = Bar(value1: 10, value2: null);
  print('bar.value: ${getType(bar.value1)}');
}

Type getType<T>(T value) => T;

class Bar<T, S extends T?> {
  final T value1;
  final S? value2;

  Bar({required this.value1, this.value2});
}

However, it forces users to pass two type arguments when the class needs to be used with the types specified explicitly. It may be a trivial matter, but it makes UX worse. Is it something that could be improved in the Dart language?

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-languageDart language related items (some items might be better tracked at github.com/dart-lang/language).type-questionA question about expected behavior or functionality

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions