-
Notifications
You must be signed in to change notification settings - Fork 27.1k
Signal Forms: Cannot bind a field of type "string | null" to a <textarea>, but can to <input> #65839
Copy link
Copy link
Closed as not planned
Closed as not planned
Copy link
Labels
area: formsforms: signalsneeds reproductionThis issue needs a reproduction in order for the team to investigate furtherThis issue needs a reproduction in order for the team to investigate further
Milestone
Description
Which @angular/* package(s) are the source of the bug?
forms
Is this a regression?
No
Description
The Signal Forms documentation explicitly calls out that optional fields should be initialized as null.
For example:
export interface PersonModel {
name: string;
bio: string | null;
}
export const DEFAULT: PersonModel = {
name: '';
bio: null;
}
@Component({ ... })
export class PersonFormComponent {
protected readonly personModel = signal<PersonModel>(DEFAULT);
protected readonly personForm = form<PersonModel>(this.personModel, (path) => {
required(path.name);
});
}The following template code is valid, as an input field can accept a field of type string | null:
<input [field]="personForm.name" />
<input [field]="personForm.bio" />However, as <input> elements cannot be multiline, attempting to replace the <input> with a <textarea> will throw a compilation error:
<input [field]="personForm.name" />
<textarea [field]="personForm.bio"></textarea>Please provide a link to a minimal reproduction of the bug
No response
Please provide the exception or error you saw
Attempting to bind to a `<textarea>` throws the following error:
Type 'string | null' is not assignable to type 'string'.
Type 'null' is not assignable to type 'string'.
Binding the same field to an `<input>` element works without the same error.
Please provide the environment you discovered this bug in (run ng version)
Angular CLI : 21.0.1
Angular : 21.0.1
Node.js : 22.16.0
Package Manager : npm 10.9.2
Operating System : linux arm64
┌────────────────────────────────────┬───────────────────┬───────────────────┐
│ Package │ Installed Version │ Requested Version │
├────────────────────────────────────┼───────────────────┼───────────────────┤
│ @angular/build │ 21.0.1 │ ^21.0.1 │
│ @angular/cdk │ 21.0.1 │ ^21.0.1 │
│ @angular/cli │ 21.0.1 │ ^21.0.1 │
│ @angular/common │ 21.0.1 │ ^21.0.1 │
│ @angular/compiler │ 21.0.1 │ ^21.0.1 │
│ @angular/compiler-cli │ 21.0.1 │ ^21.0.1 │
│ @angular/core │ 21.0.1 │ ^21.0.1 │
│ @angular/forms │ 21.0.1 │ ^21.0.1 │
│ @angular/material │ 21.0.1 │ ^21.0.1 │
│ @angular/material-date-fns-adapter │ 21.0.1 │ ^21.0.1 │
│ @angular/platform-browser │ 21.0.1 │ ^21.0.1 │
│ @angular/router │ 21.0.1 │ ^21.0.1 │
│ @angular/youtube-player │ 21.0.1 │ ^21.0.1 │
│ rxjs │ 7.8.2 │ ~7.8.0 │
│ typescript │ 5.9.3 │ ~5.9.2 │
│ vitest │ 4.0.12 │ ^4.0.12 │
└────────────────────────────────────┴───────────────────┴───────────────────┘
Anything else?
I was able to work around this by explicitly casting the field to a FieldTree<string> instead of a FieldTree<string | null> using a pipe:
<textarea [field]="personForm.bio | nullableField"></textarea>@Pipe({
name: 'nullableField',
pure: true
})
export class NullableFieldCoercionPipe implements PipeTransform {
public transform<T>(field: FieldTree<T | null>): FieldTree<T> {
return field as FieldTree<T>;
}
}As far as I can tell, untouched/unpopulated field values from a <textarea> correctly remain null if untouched by the user, so hopefully this is just a typing issue.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
area: formsforms: signalsneeds reproductionThis issue needs a reproduction in order for the team to investigate furtherThis issue needs a reproduction in order for the team to investigate further
Type
Projects
Status
Done