fix(core): allow explicit read generic with signal input transforms

Using explicit single generic arguments with transforms (for example, input<boolean>(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<boolean> | undefined): InputSignal<boolean>', gave the following error.
    Type '(value: unknown) => boolean' is not assignable to type 'undefined'.
  Overload 2 of 5, '(initialValue: undefined, opts: InputOptionsWithoutTransform<boolean>): InputSignal<boolean | undefined>', 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 1ab654cf28)
This commit is contained in:
cexbrayat 2026-04-02 12:09:30 +02:00 committed by Alex Rickabaugh
parent 08363f0f93
commit fe13bb669d
3 changed files with 29 additions and 1 deletions

View file

@ -1019,6 +1019,8 @@ export interface InputFunction {
<T>(initialValue: undefined, opts: InputOptionsWithoutTransform<T>): InputSignal<T | undefined>;
<T, TransformT>(initialValue: T, opts: InputOptionsWithTransform<T, TransformT>): InputSignalWithTransform<T, TransformT>;
<T, TransformT>(initialValue: undefined, opts: InputOptionsWithTransform<T | undefined, TransformT>): InputSignalWithTransform<T | undefined, TransformT>;
<T>(initialValue: T, opts: InputOptionsWithTransform<T, unknown>): InputSignalWithTransform<T, T>;
<T>(initialValue: undefined, opts: InputOptionsWithTransform<T | undefined, unknown>): InputSignalWithTransform<T | undefined, T | undefined>;
required: {
<T>(opts?: InputOptionsWithoutTransform<T>): InputSignal<T>;
<T, TransformT>(opts: InputOptionsWithTransform<T, TransformT>): InputSignalWithTransform<T, TransformT>;

View file

@ -77,6 +77,19 @@ export interface InputFunction {
initialValue: undefined,
opts: InputOptionsWithTransform<T | undefined, TransformT>,
): InputSignalWithTransform<T | undefined, TransformT>;
/**
* Declares an input of type `T` with an initial value and a transform function
* that accepts values of the same type.
*/
<T>(initialValue: T, opts: InputOptionsWithTransform<T, unknown>): InputSignalWithTransform<T, T>;
/**
* Declares an input of type `T|undefined` without an initial value and with a transform
* function that accepts values of the same type.
*/
<T>(
initialValue: undefined,
opts: InputOptionsWithTransform<T | undefined, unknown>,
): InputSignalWithTransform<T | undefined, T | undefined>;
/**
* Initializes a required input.

View file

@ -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<boolean>(false, {transform: booleanAttribute});
/** number, number */
explicitReadWithNumberAttributeTransform = input<number>(0, {transform: numberAttribute});
/** boolean | undefined, boolean | undefined */
explicitReadWithUndefinedInitialBooleanAttributeTransform = input<boolean>(undefined, {
transform: booleanAttribute,
});
/** number | undefined, number | undefined */
explicitReadWithUndefinedInitialNumberAttributeTransform = input<number>(undefined, {
transform: numberAttribute,
});
/** string, string | boolean */
requiredWithTransformInferenceNoExplicitGeneric = input.required({
transform: (v: string | boolean) => '',