Skip to content

[go_router_builder] Support extension types as route arguments #170870

@koji-1009

Description

@koji-1009

Use case

Using Extension types to create type-safe IDs is a common practice (e.g., extension type const ArticleId(String value) {}).

However, when this extension type is used as a path parameter in a TypedGoRoute, go_router_builder produces a build error.

Code:

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

part 'routes.g.dart';

extension type const ArticleId(String value) {}

@TypedGoRoute<RootRoute>(
  path: '/articles',
  routes: [TypedGoRoute<ArticleRoute>(path: ':id')],
)
class RootRoute extends GoRouteData with _$RootRoute {
  const RootRoute();

  @override
  Widget build(BuildContext context, GoRouterState state) {
    return const Placeholder();
  }
}

class ArticleRoute extends GoRouteData with _$ArticleRoute {
  const ArticleRoute({required this.id});

  final ArticleId id;

  @override
  Widget build(BuildContext context, GoRouterState state) {
    return const Placeholder();
  }
}

Error:

$ dart run build_runner build -d
5s go_router_builder on 2 inputs: 1 skipped, 1 no-op; spent 4s analyzing
0s source_gen:combining_builder on 2 inputs: 2 skipped

Failed to build with build_runner in 6s; wrote 0 outputs.

log output for go_router_builder on lib/routes.dart
E The parameter type `ArticleId` is not supported.
  package:builder_extension_type/routes.dart:22:37
     ╷
  22 │   const ArticleRoute({required this.id});
     │                                     ^^
     ╵

Proposal

As documented here, go_router_builder currently supports path parameter types like String and int:
https://github.com/flutter/packages/tree/main/packages/go_router_builder#type-conversions

I propose extending this support to extension type. Here is an image of the generated code.

mixin _$ArticleRoute on GoRouteData {
  static ArticleRoute _fromState(GoRouterState state) =>
      ArticleRoute(id: state.pathParameters['id']! as ArticleId);

  ArticleRoute get _self => this as ArticleRoute;

  @override
  String get location =>
      GoRouteData.$location('/articles/${Uri.encodeComponent(_self.id.toString())}');

  @override
  void go(BuildContext context) => context.go(location);

  @override
  Future<T?> push<T>(BuildContext context) => context.push<T>(location);

  @override
  void pushReplacement(BuildContext context) =>
      context.pushReplacement(location);

  @override
  void replace(BuildContext context) => context.replace(location);
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3Issues that are less important to the Flutter projectc: new featureNothing broken; request for a new capabilityc: proposalA detailed proposal for a change to Flutterp: go_router_builderThe go_router_builder packagepackageflutter/packages repository. See also p: labels.r: fixedIssue is closed as already fixed in a newer versionteam-frameworkOwned by Framework teamtriaged-frameworkTriaged by Framework team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions