해결된 질문
작성
·
191
3
안녕하세요. 코팩님!
[고급 캐시관리] 파트의 PaginationListView와 PaginationWidgetBuilder에서 제네릭을 처리하는 부분에 있어 타입 추론이 명확하게 되지 않는 부분이 있습니다.
class PaginationListView<T extends IModelWithId> extends ConsumerStatefulWidget {
final StateNotifierProvider<PaginationProvider, CursorPaginationBase> provider;
final PaginationWidgetBuilder<T> itemBuilder;
...
@override
ConsumerState<PaginationListView> createState() => _PaginationListViewState<T>();
}
class _PaginationListViewState<T extends IModelWithId> extends ConsumerState<PaginationListView> {
...
여기서 _PaginationListViewState 클래스는 ConsumerState<PaginationListView>를 상속 받으면서 정확하게는 ConsumerState<PaginationListView<dynamic>>을 상속하게 됩니다.
이로 인해 State클래스 내부에서 호출하는 itemBuilder는 PaginationWidgetBuilder<dynamic>으로 동작하여 실제 사용하는 코드 부분에서 itemBuilder 파라미터에 빌더 작성시 일반적으로는 아래와 같은 에러가 발생합니다.
type '(BuildContext, int, RestaurantModel) => Widget' is not a subtype of type '(BuildContext, int, IModelWithId) => Widget'
이에 builder Function 앞에 강의 내용처럼<RestaurantModel>을 선언하여 에러를 회피할 수 있지만, 이럴 경우 빌더에 전달되는 파라미터는 전부 dynamic으로 추론되는 것을 확인했습니다.
그리고, 새로운 익명함수를 정의하는 형태라 그런지 앞에 <RestaurantModel>가 아닌 아무 의미 없이 <ABC>를 적어도 빌드나 실제 앱 동작에 아무런 문제가 없습니다.
그래서 빌더 함수 내부에서model.
을 입력하더라도 dynamic 이기 때문에 실제로 목표로 하는 모델의 속성들이 자동완성 제안이 되지 않고 런타임에서 대입됩니다.
class _PaginationListViewState<T extends IModelWithId> extends ConsumerState<PaginationListView<T>> {
...
위와 같이 State 클래스에서 선언한 제네릭 T를 이용해서 PaginationListView<T>의 ConsumerState 임을 명시했을 때, State클래스 내부의 itemBuilder가 PaginationWidgetBuilder<T>로 잘 동작했습니다.
타입이 명확하므로 builder Function에 <RestaurantModel>을 쓰지 않아도 정확한 타입을 전달해줬습니다.
마찬가지로
final StateNotifierProvider<PaginationProvider, CursorPaginationBase> provider;
이 부분도 제네릭을 명시해야 실제 해당 뷰의 모델에 맞는 프로바이더만 주입 가능하기 때문에 더 나을 것 같습니다.
dynamic이 넘어오는게 의아해서, 혼자 이리저리 해보면서 궁금증을 해결했는데 강의에 괜찮은 피드백이 될까 싶어서 글 남깁니다 :)
좋은 강의 감사드립니다.
내용이 좋아서 시간 가는 줄 모르고 꾸준히 듣고 있네요!
답변 1
2