Skip to content

Self type #3025

Open
Open
@Hixie

Description

@Hixie

It'd be nice if a type could reliably refer to an implicit generic type argument representing the type of the instance.

Today you have to do something like:

abstract class Foo<Self extends Foo<Self>> { }

Now subclasses have to specify themselves as the type argument:

class BarFoo extends Foo<BarFoo> { }

This leads to some weird errors when people aren't explicit about types (see dart-lang/sdk#52204).

It also isn't completely safe. For example, I could copy and paste BarFoo to make BazFoo and make a mistake and not notice for a while:

class BazFoo extends Foo<BarFoo> { } // no error, but the Self type is wrong

Use case

I use this for classes that declare an API that I want to use in other generic contexts, e.g.:

@immutable
abstract class Status<S extends Status<S>> {
  const Status();
  S copyWith();
  S lerpTo(S other, double t);
  bool matches(S other);

  @override
  operator ==(Object other) {
    if (other.runtimeType != runtimeType)
      return false;
    return matches(other as S);
  }
}

Now I have a type that I know I can clone, lerp, and compare, and so algorithms that are generic over that API can work on all the various subclasses of this type without needing to worry about the details.

(Obviously, true metaclasses would make this even more powerful, but I think this stands alone even without metaclasses.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureProposed language feature that solves one or more problems

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions