Skip to content

There's no good way to promote a field #35525

Open
@Hixie

Description

@Hixie

(This bug assumes a world with implicit-casts: false.)

If I have a class with a field of unknown type, there's currently no clean way to write the code that handles that field in a type-safe way, as far as I can tell.

class Bar<T, R, S> {
  Bar(this.value);
  final Object value;

  void foo() {
    if (value.runtimeType == runtimeType) {
      // ok we know it's the same type as us, but neither the analyzer nor the compiler agree
      final Bar<T, R, S> typedValue = value as Bar<T, R, S>; // this line is really ugly.
      // not we can use typedValue, but that's ugly.
      typedValue.la(1);
      typedValue.la(2);
      typedValue.la(3);
    }
    // ...
  }
  void la(int x) { }
}
class Bar<T, R, S> {
  Bar(this.value);
  final dynamic value;

  void foo() {
    if (value.runtimeType == runtimeType) {
      // ok we know it's the same type as us, but neither the analyzer nor the compiler agree
      // so we get no type checking here
      value.la(1);
      value.la(2);
      value.laa(3); // oops typo, nobody will notice until runtime
    }
    // ...
  }
  void la(int x) { }
}
class Bar<T, R, S> {
  Bar(this.value);
  final Object value;

  void foo() {
    if (value.runtimeType == runtimeType) {
      // ok we know it's the same type as us, but neither the analyzer nor the compiler agree
      assert(value is Bar<T, R, S>); // this doesn't do anything for the compiler or the analyzer
      value.la(1); // the compiler doesn't allow this
      value.la(2);
      value.la(3);
    }
    // ...
  }
  void la(int x) { }
}
class Bar<T, R, S> {
  Bar(this.value);
  final Object value;

  void foo() {
    if (value.runtimeType == runtimeType) {
      // ok we know it's the same type as us, but neither the analyzer nor the compiler agree
      if (value is Bar<T, R, S>) { // this doesn't do anything for the compiler or the analyzer
        value.la(1); // the compiler doesn't allow this
        value.la(2);
        value.la(3);
      }
    }
    // ...
  }
  void la(int x) { }
}

What is the preferred way to write this code?

I've run into this in various places but most recently when writing a class to represent Json data.

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

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions