diff --git a/goldens/public-api/core/index.api.md b/goldens/public-api/core/index.api.md index 271578483f5..b39c3e1242e 100644 --- a/goldens/public-api/core/index.api.md +++ b/goldens/public-api/core/index.api.md @@ -1029,8 +1029,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; + (initialValue: T, opts: InputOptionsWithTransform): InputSignalWithTransform; + (initialValue: undefined, opts: InputOptionsWithTransform): InputSignalWithTransform; required: { (opts?: InputOptionsWithoutTransform): InputSignal; (opts: InputOptionsWithTransform): InputSignalWithTransform; diff --git a/packages/compiler-cli/test/ngtsc/authoring_inputs_spec.ts b/packages/compiler-cli/test/ngtsc/authoring_inputs_spec.ts index 6122cfd3720..c5831b81254 100644 --- a/packages/compiler-cli/test/ngtsc/authoring_inputs_spec.ts +++ b/packages/compiler-cli/test/ngtsc/authoring_inputs_spec.ts @@ -320,6 +320,66 @@ runInEachFileSystem(() => { ); }); + it('should allow text attributes for explicit signal inputs with booleanAttribute transform', () => { + env.write( + 'test.ts', + ` + import {booleanAttribute, Component, Directive, input} from '@angular/core'; + + @Directive({ + selector: '[directiveName]', + }) + export class TestDir { + dismissible = input(true, {transform: booleanAttribute}); + } + + @Component({ + template: \` +
+
+
+ \`, + imports: [TestDir], + }) + export class TestComp { + } + `, + ); + + const diagnostics = env.driveDiagnostics(); + expect(diagnostics).toEqual([]); + }); + + it('should allow text attributes for explicit signal inputs with numberAttribute transform', () => { + env.write( + 'test.ts', + ` + import {Component, Directive, input, numberAttribute} from '@angular/core'; + + @Directive({ + selector: '[directiveName]', + }) + export class TestDir { + count = input(0, {transform: numberAttribute}); + } + + @Component({ + template: \` +
+
+
+ \`, + imports: [TestDir], + }) + export class TestComp { + } + `, + ); + + const diagnostics = env.driveDiagnostics(); + expect(diagnostics).toEqual([]); + }); + it('should report unset required inputs', () => { env.write( 'test.ts', diff --git a/packages/core/src/authoring/input/input.ts b/packages/core/src/authoring/input/input.ts index dcc4394f8a8..6f1d6396249 100644 --- a/packages/core/src/authoring/input/input.ts +++ b/packages/core/src/authoring/input/input.ts @@ -79,17 +79,20 @@ export interface InputFunction { ): InputSignalWithTransform; /** * Declares an input of type `T` with an initial value and a transform function - * that accepts values of the same type. + * that accepts values of the same type, or string values from static attributes. */ - (initialValue: T, opts: InputOptionsWithTransform): InputSignalWithTransform; + ( + 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. + * function that accepts values of the same type, or string values from static attributes. */ ( initialValue: undefined, opts: InputOptionsWithTransform, - ): InputSignalWithTransform; + ): 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 5f1d0a060ab..1e929326911 100644 --- a/packages/core/test/authoring/signal_input_signature_test.ts +++ b/packages/core/test/authoring/signal_input_signature_test.ts @@ -102,15 +102,15 @@ export class InputSignatureTest { transform: (v: string | boolean) => '', }); - /** boolean, boolean */ + /** boolean, string | boolean */ explicitReadWithBooleanAttributeTransform = input(false, {transform: booleanAttribute}); - /** number, number */ + /** number, string | number */ explicitReadWithNumberAttributeTransform = input(0, {transform: numberAttribute}); - /** boolean | undefined, boolean | undefined */ + /** boolean | undefined, string | boolean | undefined */ explicitReadWithUndefinedInitialBooleanAttributeTransform = input(undefined, { transform: booleanAttribute, }); - /** number | undefined, number | undefined */ + /** number | undefined, string | number | undefined */ explicitReadWithUndefinedInitialNumberAttributeTransform = input(undefined, { transform: numberAttribute, });