Skip to content

Commit d0097f7

Browse files
mmalerbaalxhub
authored andcommitted
fix(forms): fix signal forms type error
Removes the `implements` clause on the `Field` directive since it is causing type errors for people.
1 parent 4f6014a commit d0097f7

3 files changed

Lines changed: 11 additions & 5 deletions

File tree

goldens/public-api/forms/signals/compat/index.api.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import { ValidationErrors } from '@angular/forms';
1717
import { ValidatorFn } from '@angular/forms';
1818
import { WritableSignal } from '@angular/core';
1919
import { ɵCONTROL } from '@angular/core';
20-
import { ɵControl } from '@angular/core';
2120
import { ɵcontrolUpdate } from '@angular/core';
2221
import { ɵFieldState } from '@angular/core';
2322
import { ɵɵcontrolCreate } from '@angular/core';

goldens/public-api/forms/signals/index.api.md

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import { ValidationErrors } from '@angular/forms';
2727
import { ValidatorFn } from '@angular/forms';
2828
import { WritableSignal } from '@angular/core';
2929
import { ɵCONTROL } from '@angular/core';
30-
import { ɵControl } from '@angular/core';
3130
import { ɵcontrolUpdate } from '@angular/core';
3231
import { ɵFieldState } from '@angular/core';
3332
import { ɵɵcontrolCreate } from '@angular/core';
@@ -139,7 +138,7 @@ export class EmailValidationError extends _NgValidationError {
139138
export const FIELD: InjectionToken<Field<unknown>>;
140139

141140
// @public
142-
export class Field<T> implements ɵControl<T> {
141+
export class Field<T> {
143142
// (undocumented)
144143
readonlyCONTROL]: {
145144
readonly create: typeof ɵɵcontrolCreate;

packages/forms/signals/src/api/field_directive.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ import {
1818
input,
1919
ɵcontrolUpdate as updateControlBinding,
2020
ɵCONTROL,
21-
ɵControl,
2221
ɵInteropControl,
22+
type ɵControl,
2323
} from '@angular/core';
2424
import {NG_VALUE_ACCESSOR, NgControl} from '@angular/forms';
2525
import {InteropNgControl} from '../controls/interop_ng_control';
@@ -71,7 +71,10 @@ const controlInstructions = {
7171
{provide: NgControl, useFactory: () => inject(Field).getOrCreateNgControl()},
7272
],
7373
})
74-
export class Field<T> implements ɵControl<T> {
74+
// This directive should `implements ɵControl<T>`, but actually adding that breaks people's
75+
// builds because part of the public API is marked `@internal` and stripped.
76+
// Instead we have an type check below that enforces this in a non-breaking way.
77+
export class Field<T> {
7578
readonly element = inject<ElementRef<HTMLElement>>(ElementRef).nativeElement;
7679
readonly injector = inject(Injector);
7780
readonly field = input.required<FieldTree<T>>();
@@ -127,3 +130,8 @@ export class Field<T> implements ɵControl<T> {
127130
);
128131
}
129132
}
133+
134+
// We can't add `implements ɵControl<T>` to `Field` even though it should conform to the interface.
135+
// Instead we enforce it here through some utility types.
136+
type Check<T extends true> = T;
137+
type FieldImplementsɵControl = Check<Field<any> extends ɵControl<any> ? true : false>;

0 commit comments

Comments
 (0)