DEV Community

HarmonyOS
HarmonyOS

Posted on

The WrappedBuilder error indicates a mismatch in generic parameter types.

Read the original article:The WrappedBuilder error indicates a mismatch in generic parameter types.

Context

When using WrappedBuilder to maintain UI, developers may encounter TypeScript generic errors, particularly when the generic type T does not match the expected type in WrappedBuilder or DialogCustomV2.

Description

The error occurs because generic parameter types do not match. DialogCustomV2<T> cannot be assigned to DialogCustomV2<BaseCustomDialogParam>. Even though BaseCustomDialogParam satisfies the constraint of T, T can be instantiated with any subtype, causing incompatibility.

Argument of type 'DialogCustomV2<T>' is not assignable to parameter of type 'MAPPER_VALUE'.
Type 'DialogCustomV2<T>' is not assignable to type 'DialogCustomV2<BaseCustomDialogParam>'.
The types of 'wrapped.builder' are incompatible between these types.
Type '(args_0: T) => void' is not assignable to type '(args_0: BaseCustomDialogParam) => void'.
Types of parameters 'args_0' and 'args_0' are incompatible.
Type 'BaseCustomDialogParam' is not assignable to type 'T'.
Enter fullscreen mode Exit fullscreen mode

Solution / Approach

  • To ensure type safety when using WrappedBuilder, DialogCustomV2<T> and wrapped: WrappedBuilder<[T]> should use the specific type you want to operate on, rather than the generic type T.
  • In this example, both DialogCustomV2 and WrappedBuilder should use BaseCustomDialogParam as the type.

DialogCustomV2 constructor:

constructor(wrapped: WrappedBuilder<[T]>, param: T, dialogParam?: Param.BaseDialogParamV2) {
    this.wrapped = wrapped
    this.param = param
    if (param.onClose === undefined) {
      param.onClose = () => {
        this.close()
        return true
      }
    } else {
      const cus = param.onClose
      param.onClose = () => {
        const res = cus()
        res ? this.close() : undefined
        return true
      }
    }
    this._id = simpleUUID()
    this.dialogParam = dialogParam ?? {}
    this.dialogId = 0
}
Enter fullscreen mode Exit fullscreen mode

Modified, type-safe code:

export function showCustomV2<T extends Param.BaseCustomDialogParam>(
  wrapped: WrappedBuilder<[Param.BaseCustomDialogParam]>,
  param: T,
  dialogParam?: Param.BaseDialogParamV2
) {
  const dialog: DialogCustomV2<Param.BaseCustomDialogParam> =
    new DialogCustomV2<Param.BaseCustomDialogParam>(wrapped, param, dialogParam)
  MAPPER.set(dialog.id, dialog)
  STACK.push(dialog.id)
  dialog.open()
}
Enter fullscreen mode Exit fullscreen mode

Key Takeaways

  • Generic type mismatch occurs because T can be instantiated with any subtype of BaseCustomDialogParam, making WrappedBuilder<[T]> incompatible with WrappedBuilder<[BaseCustomDialogParam]>.
  • Solution: Use a concrete type (BaseCustomDialogParam) in DialogCustomV2 and WrappedBuilder to maintain type safety.
  • Always ensure that when using generics in UI builders, the types passed in are consistent across all layers (DialogCustomV2, WrappedBuilder, MAPPER, STACK).

Additional Resources

https://developer.huawei.com/consumer/en/doc/harmonyos-references/ts-methods-custom-dialog-box

Written by Mehmet Algul

Top comments (0)