Skip to content

Instantly share code, notes, and snippets.

@dnys1
Created May 5, 2023 19:00
Show Gist options
  • Save dnys1/13df1a20b5a686580572d7e4d187e1c7 to your computer and use it in GitHub Desktop.
Save dnys1/13df1a20b5a686580572d7e4d187e1c7 to your computer and use it in GitHub Desktop.
bustling-aurora-9307

bustling-aurora-9307

Created with <3 with dartpad.dev.

abstract class PluginOptions {}
abstract class Plugin<Options extends PluginOptions> {
Options get options;
}
class MyPluginOptions extends PluginOptions {}
class MyPlugin extends Plugin<MyPluginOptions> {
static const pluginKey = PluginKey<MyPluginOptions, MyPlugin>();
@override
MyPluginOptions get options => MyPluginOptions();
}
O getOptionsGenerically<O extends PluginOptions, P extends Plugin<O>>(P plugin) => plugin.options;
class PluginKey<O extends PluginOptions, P extends Plugin<O>> {
const PluginKey();
}
O getOptionsWithPluginKey<O extends PluginOptions, P extends Plugin<O>>(PluginKey<O, P> pluginKey, P plugin) => plugin.options;
void main() {
final plugin = MyPlugin();
// Problem: The static type = `PluginOptions` but we want `MyPluginOptions`.
//
// This is due to limitations in Dart's ability to infer generics when referemce each other.
final /* PluginOptions */ options = getOptionsGenerically(plugin);
// Option 1: pass all generic types explicitly.
//
// But you have to know which parameters to pass, and for anything more than 2 parameters, it's very verbose.
final /* MyPluginOptions */ myPluginOptions = getOptionsGenerically<MyPluginOptions, MyPlugin>(plugin);
// Option 2: plugin key
//
// The plugin key encodes the generic parameters so that we don't have to remember them/pass them specifically.
// The plugin key is also easier to locate when it has a dedicated location per plugin.
final /* MyPluginOptions */ myPluginKeyOptions = getOptionsWithPluginKey(MyPlugin.pluginKey, plugin);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment