From fe13bb669d2bfab4713623d17b41c430aa0a61d8 Mon Sep 17 00:00:00 2001 From: cexbrayat Date: Thu, 2 Apr 2026 12:09:30 +0200 Subject: [PATCH] fix(core): allow explicit read generic with signal input transforms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Using explicit single generic arguments with transforms (for example, input(false, {transform: booleanAttribute})) previously failed overload resolution. Before this fix, type-checking produced: ```` ✘ [ERROR] TS2769: No overload matches this call. Overload 1 of 5, '(initialValue: boolean, opts?: InputOptionsWithoutTransform | undefined): InputSignal', gave the following error. Type '(value: unknown) => boolean' is not assignable to type 'undefined'. Overload 2 of 5, '(initialValue: undefined, opts: InputOptionsWithoutTransform): InputSignal', gave the following error. Argument of type 'true' is not assignable to parameter of type 'undefined'. [plugin angular-compiler] ``` This change adds specialized overloads for explicit read generics. (cherry picked from commit 1ab654cf281559294bdd3b900ad81490cb91007f) --- goldens/public-api/core/index.api.md | 2 ++ packages/core/src/authoring/input/input.ts | 13 +++++++++++++ .../test/authoring/signal_input_signature_test.ts | 15 ++++++++++++++- 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/goldens/public-api/core/index.api.md b/goldens/public-api/core/index.api.md index 7f0237fc9ae..48348e13ec4 100644 --- a/goldens/public-api/core/index.api.md +++ b/goldens/public-api/core/index.api.md @@ -1019,6 +1019,8 @@ export interface InputFunction { (initialValue: undefined, opts: InputOptionsWithoutTransform): InputSignal; (initialValue: T, opts: InputOptionsWithTransform): InputSignalWithTransform; (initialValue: undefined, opts: InputOptionsWithTransform): InputSignalWithTransform; + (initialValue: T, opts: InputOptionsWithTransform): InputSignalWithTransform; + (initialValue: undefined, opts: InputOptionsWithTransform): InputSignalWithTransform; required: { (opts?: InputOptionsWithoutTransform): InputSignal; (opts: InputOptionsWithTransform): InputSignalWithTransform; diff --git a/packages/core/src/authoring/input/input.ts b/packages/core/src/authoring/input/input.ts index a88007cd41b..dcc4394f8a8 100644 --- a/packages/core/src/authoring/input/input.ts +++ b/packages/core/src/authoring/input/input.ts @@ -77,6 +77,19 @@ export interface InputFunction { initialValue: undefined, opts: InputOptionsWithTransform, ): InputSignalWithTransform; + /** + * Declares an input of type `T` with an initial value and a transform function + * that accepts values of the same type. + */ + (initialValue: T, opts: InputOptionsWithTransform): InputSignalWithTransform; + /** + * Declares an input of type `T|undefined` without an initial value and with a transform + * function that accepts values of the same type. + */ + ( + initialValue: undefined, + opts: InputOptionsWithTransform, + ): InputSignalWithTransform; /** * Initializes a required input. diff --git a/packages/core/test/authoring/signal_input_signature_test.ts b/packages/core/test/authoring/signal_input_signature_test.ts index ba4a8c3c2e3..5f1d0a060ab 100644 --- a/packages/core/test/authoring/signal_input_signature_test.ts +++ b/packages/core/test/authoring/signal_input_signature_test.ts @@ -12,7 +12,7 @@ * the resulting types match our expectations (via comments asserting the `.d.ts`). */ -import {input} from '../../src/core'; +import {booleanAttribute, input, numberAttribute} from '../../src/core'; // import preserved to simplify `.d.ts` emit and simplify the `type_tester` logic. // tslint:disable-next-line no-duplicate-imports import {InputSignal, InputSignalWithTransform} from '../../src/core'; @@ -102,6 +102,19 @@ export class InputSignatureTest { transform: (v: string | boolean) => '', }); + /** boolean, boolean */ + explicitReadWithBooleanAttributeTransform = input(false, {transform: booleanAttribute}); + /** number, number */ + explicitReadWithNumberAttributeTransform = input(0, {transform: numberAttribute}); + /** boolean | undefined, boolean | undefined */ + explicitReadWithUndefinedInitialBooleanAttributeTransform = input(undefined, { + transform: booleanAttribute, + }); + /** number | undefined, number | undefined */ + explicitReadWithUndefinedInitialNumberAttributeTransform = input(undefined, { + transform: numberAttribute, + }); + /** string, string | boolean */ requiredWithTransformInferenceNoExplicitGeneric = input.required({ transform: (v: string | boolean) => '',