From ee8d2098cb3cdce1589c462cd9a66eae490477f9 Mon Sep 17 00:00:00 2001 From: Alex Rickabaugh Date: Mon, 23 Mar 2026 13:01:09 -0700 Subject: [PATCH] fix(forms): change FieldState optional properties to non-optional | undefined This improves compatibility with TypeScript's exactOptionalPropertyTypes. Fixes #67246 --- goldens/public-api/forms/signals/index.api.md | 16 ++++---- .../forms/signals/src/api/rules/metadata.ts | 12 +++--- .../api/rules/validation/validate_async.ts | 2 +- packages/forms/signals/src/api/types.ts | 8 ++-- packages/forms/signals/src/field/metadata.ts | 37 +++++++++++------- packages/forms/signals/src/field/node.ts | 3 ++ packages/forms/signals/src/schema/logic.ts | 4 ++ .../forms/signals/test/node/resource.spec.ts | 39 +++++++++++++++++-- 8 files changed, 85 insertions(+), 36 deletions(-) diff --git a/goldens/public-api/forms/signals/index.api.md b/goldens/public-api/forms/signals/index.api.md index 608d8ce09e0..e48672db9c1 100644 --- a/goldens/public-api/forms/signals/index.api.md +++ b/goldens/public-api/forms/signals/index.api.md @@ -79,10 +79,10 @@ export type CompatSchemaPath(create: (s: Signal) => TRead): MetadataKey; +export function createManagedMetadataKey(create: (state: FieldState, data: Signal) => TRead): MetadataKey; // @public -export function createManagedMetadataKey(create: (s: Signal) => TRead, reducer: MetadataReducer): MetadataKey; +export function createManagedMetadataKey(create: (state: FieldState, data: Signal) => TRead, reducer: MetadataReducer): MetadataKey; // @public export function createMetadataKey(): MetadataKey, TWrite, TWrite | undefined>; @@ -345,9 +345,9 @@ export function metadata, TPathK // @public export class MetadataKey { - protected constructor(reducer: MetadataReducer, create: ((s: Signal) => TRead) | undefined); + protected constructor(reducer: MetadataReducer, create: ((state: FieldState, data: Signal) => TRead) | undefined); // (undocumented) - readonly create: ((s: Signal) => TRead) | undefined; + readonly create: ((state: FieldState, data: Signal) => TRead) | undefined; // (undocumented) readonly reducer: MetadataReducer; } @@ -509,11 +509,11 @@ export interface ReadonlyFieldState; readonly invalid: Signal; readonly keyInParent: Signal; - readonly max?: Signal; - readonly maxLength?: Signal; + readonly max: Signal | undefined; + readonly maxLength: Signal | undefined; metadata(key: MetadataKey): M | undefined; - readonly min?: Signal; - readonly minLength?: Signal; + readonly min: Signal | undefined; + readonly minLength: Signal | undefined; readonly name: Signal; readonly pattern: Signal; readonly pending: Signal; diff --git a/packages/forms/signals/src/api/rules/metadata.ts b/packages/forms/signals/src/api/rules/metadata.ts index ef5b19d9888..090ba490923 100644 --- a/packages/forms/signals/src/api/rules/metadata.ts +++ b/packages/forms/signals/src/api/rules/metadata.ts @@ -9,7 +9,7 @@ import {type Signal} from '@angular/core'; import {FieldPathNode} from '../../schema/path_node'; import {assertPathIsCurrent} from '../../schema/schema'; -import type {LogicFn, PathKind, SchemaPath, SchemaPathRules} from '../types'; +import type {FieldState, LogicFn, PathKind, SchemaPath, SchemaPathRules} from '../types'; /** * Sets a value for the {@link MetadataKey} for this field. @@ -150,7 +150,7 @@ export class MetadataKey { /** Use {@link reducedMetadataKey}. */ protected constructor( readonly reducer: MetadataReducer, - readonly create: ((s: Signal) => TRead) | undefined, + readonly create: ((state: FieldState, data: Signal) => TRead) | undefined, ) {} } @@ -211,7 +211,7 @@ export function createMetadataKey( * @experimental 21.0.0 */ export function createManagedMetadataKey( - create: (s: Signal) => TRead, + create: (state: FieldState, data: Signal) => TRead, ): MetadataKey; /** * Creates a metadata key that exposes a managed value based on the accumulated result of the values @@ -229,16 +229,16 @@ export function createManagedMetadataKey( * @experimental 21.0.0 */ export function createManagedMetadataKey( - create: (s: Signal) => TRead, + create: (state: FieldState, data: Signal) => TRead, reducer: MetadataReducer, ): MetadataKey; export function createManagedMetadataKey( - create: (s: Signal) => TRead, + create: (state: FieldState, data: Signal) => TRead, reducer?: MetadataReducer, ): MetadataKey { return new (MetadataKey as new ( reducer: MetadataReducer, - create: (s: Signal) => TRead, + create: (state: FieldState, data: Signal) => TRead, ) => MetadataKey)(reducer ?? MetadataReducer.override(), create); } diff --git a/packages/forms/signals/src/api/rules/validation/validate_async.ts b/packages/forms/signals/src/api/rules/validation/validate_async.ts index 0ef8f5d9201..b6c16890f93 100644 --- a/packages/forms/signals/src/api/rules/validation/validate_async.ts +++ b/packages/forms/signals/src/api/rules/validation/validate_async.ts @@ -118,7 +118,7 @@ export function validateAsync, TParams | undefined>( - opts.factory, + (_state, params) => opts.factory(params), ); RESOURCE[IS_ASYNC_VALIDATION_RESOURCE] = true; diff --git a/packages/forms/signals/src/api/types.ts b/packages/forms/signals/src/api/types.ts index b624f350cb0..0c5ed44d42a 100644 --- a/packages/forms/signals/src/api/types.ts +++ b/packages/forms/signals/src/api/types.ts @@ -346,28 +346,28 @@ export interface ReadonlyFieldState` with a numeric or date `type` attribute and custom controls. */ - readonly max?: Signal; + readonly max: Signal | undefined; /** * A signal indicating the field's maximum string length, if applicable. * * Applies to ``, `