XrmDefinitelyTyped icon indicating copy to clipboard operation
XrmDefinitelyTyped copied to clipboard

`formContext.getControl("somelogicalname")` is not assignable to `Xrm.AnyControl`

Open vandenberghev opened this issue 3 years ago • 3 comments

Describe the bug

I'm having issues with controls obtained through formContext.getControl("somelogicalname"). For some reason, they appear not to be assignable to AnyControl, even though the type ticks all the boxes.

To Reproduce

const executionContext: Xrm.ExecutionContext<...>;
const formContext = executionContext.getFormContext() as Form...;
const optionSetControl = formContext.getControl("somelogicalname"); //OptionSetControl<boolean> for example
const anyControl: Xrm.AnyControl = optionSetControl;

Expected behavior

I expect the OptionSetControl<T> to be assignable to AnyControl; it's clearly included in the typing.

Screenshots

image

Environment

  • CRM/D365/CDS version: v9.1
  • Tool version: Delegate.XrmDefinitelyTyped v5.4.2
  • In Visual Studio 2019 v16.8.3

Other info Currently working around this problem by using a type assertion:

const anyControl: Xrm.AnyControl = optionSetControl as Xrm.AnyControl;

This seems to work.

vandenberghev avatar May 27 '21 15:05 vandenberghev

Apparently not limited to just OptionSetControl<T>, sorry. Something got lost in translation between a colleague and myself - I'm just the messenger :)

I'm having trouble understanding where the unknown in Control<OptionSetAttribute<unknown>> comes from, as I assign it a properly typed OptionSetControl<boolean>... But maybe this is behavior as intended?

vandenberghev avatar May 28 '21 12:05 vandenberghev

I agree, there seems to be some discrepancy with AnyControl. It contains all methods of the included controls, not just the shared methods. I double-checked the documentation (https://docs.microsoft.com/en-us/powerapps/developer/model-driven-apps/clientapi/reference/controls), and the following methods should be included, as far as I can see:

  • getControlType
  • getDisabled
  • getName
  • getParent
  • getVisible
  • setFocus
  • setVisible

get/setLabel are already included, but should not be. They are not part of Subgrid control. setDisabled is not part of kbsearch control.

I'm not sure I managed to get an in-depth overview of the relevant controls, but, as stated, it seems to me there's too many methods included in baseControl., and some subsequent usages ought to reference other controls.

misoeli avatar May 28 '21 20:05 misoeli

I'm not sure if the get-/setLabel functions are actually a mistake or if the documentation has simply omitted them by mistake. The documentation for the individual functions states that they support all control types. I've created an issue in Microsoft's documentation to clarify this.

skovlund avatar Mar 25 '22 11:03 skovlund

I think we all misunderstood the intended use of Xrm.AnyControl.

It is intended as a catch-all when working with an unspecified control, where we don't want to limit typings to any specific control, and therefore include typings for any function that is supported by at least one control type. Just like the type any is used when the type is unknown and should support any function. This is why its typing is a union of all control types instead of an intersection.

It is still possible to cast any control (including the OptionSetControl) to AnyControl but it should be downcast instead of upcast (as originally described as a workaround). Note that such a cast includes typings for functions that are not supported by the OptionSetControl, and therefore is rarely the intended cast.

Downcast Option-Set-Control to Any-Control

The OptionSetControl can be upcast to the types it extends, which includes BaseControl. This limits the typings to functions supported by all controls, and therefore does not permit using functions that are not supported by the OptionSetControl.

Upcast Option-Set-Control to Base-Control

skovlund avatar Nov 27 '23 11:11 skovlund