Repository: angular/angular
File: packages/forms/signals/src/api/form_field_directive.ts (TypeScript)

Code before:
  private interopNgControl: InteropNgControl | undefined;

  /**
   * A `ControlValueAccessor`, if configured, for the host component.
   *
   * @internal
   */
  get ɵinteropControl(): ɵInteropControl | undefined {
    return this.controlValueAccessors?.[0] ?? this.interopNgControl?.valueAccessor ?? undefined;
  }

  /** Lazily instantiates a fake `NgControl` for this form field. */
  protected getOrCreateNgControl(): InteropNgControl {
    return (this.interopNgControl ??= new InteropNgControl(this.state));
  }

  /**
   * Registers this `FormField` as a binding on its associated `FieldState`.
   *
   * This method should be called at most once for a given `FormField`. A `FormField` placed on a
   * custom control (`FormUiControl`) automatically registers that custom control as a binding.
   */
  registerAsBinding(bindingOptions?: FormFieldBindingOptions) {
    if (untracked(this.bindingOptions)) {
      throw Error('FormField is already registered as a binding.');
    }

    this.bindingOptions.set(bindingOptions);
    // Register this control on the field state it is currently bound to. We do this at the end of
    // initialization so that it only runs if we are actually syncing with this control
    // (as opposed to just passing the field state through to its `formField` input).
    effect(
      (onCleanup) => {
        const fieldNode = this.state() as unknown as FieldNode;
        fieldNode.nodeState.formFieldBindings.update((controls) => [
          ...controls,
          this as FormField<unknown>,
        ]);
        onCleanup(() => {
          fieldNode.nodeState.formFieldBindings.update((controls) =>
            controls.filter((c) => c !== this),
          );
        });
      },
      {injector: this.injector},
    );
  }

  /** Focuses this UI control. */
  focus() {
    const bindingOptions = untracked(this.bindingOptions);

Review comment (suggestion):
Maybe add a TODO to make that a `RuntimeError` with a tree-shakable runtime error. 

Code after:

  /** A lazily instantiated fake `NgControl`. */
  private interopNgControl: InteropNgControl | undefined;

  /**
   * A `ControlValueAccessor`, if configured, for the host component.
   *
   * @internal
   */
  get ɵinteropControl(): ɵInteropControl | undefined {
    return this.controlValueAccessors?.[0] ?? this.interopNgControl?.valueAccessor ?? undefined;
  }

  /** Lazily instantiates a fake `NgControl` for this form field. */
  protected getOrCreateNgControl(): InteropNgControl {
    return (this.interopNgControl ??= new InteropNgControl(this.state));
  }

  /**
   * Registers this `FormField` as a binding on its associated `FieldState`.
   *
   * This method should be called at most once for a given `FormField`. A `FormField` placed on a
   * custom control (`FormUiControl`) automatically registers that custom control as a binding.
   */
  registerAsBinding(bindingOptions?: FormFieldBindingOptions) {
    if (untracked(this.bindingOptions)) {
      throw new RuntimeError(
        SignalFormsErrorCode.BINDING_ALREADY_REGISTERED,
        ngDevMode && 'FormField already registered as a binding',
      );
    }

    this.bindingOptions.set(bindingOptions);
    // Register this control on the field state it is currently bound to. We do this at the end of
    // initialization so that it only runs if we are actually syncing with this control
    // (as opposed to just passing the field state through to its `formField` input).
    effect(
      (onCleanup) => {
        const fieldNode = this.state() as unknown as FieldNode;
        fieldNode.nodeState.formFieldBindings.update((controls) => [
          ...controls,
          this as FormField<unknown>,
        ]);
        onCleanup(() => {
          fieldNode.nodeState.formFieldBindings.update((controls) =>
            controls.filter((c) => c !== this),
          );
        });
      },
      {injector: this.injector},
    );