primefaces / primeng

The Most Complete Angular UI Component Library
https://primeng.org
Other
9.84k stars 4.5k forks source link

keyFilter: ngModelChange typings breaks usage in primeng 16 #13147

Open cghislai opened 1 year ago

cghislai commented 1 year ago

Describe the bug

When using primeng 16 rc2, the keyFilter directive prevents its usage on a component that use ngModel 2-way bindings with a controller value that is not of type string | number.

For instance, a component defining a controller value value: string | undefied that is bound to a text input field using the keyFilter directive, for instance:

<input type="text" pInputText [(ngModel)]="value" [pKeyFilter]="'[a-z]+'" [pValidateOnly]="true">

The template compilation fails, because the typings constraints on value imposed by the pKeyFilter directive (string | number) do not match the declared type (string | undefined). This is because the directive emits a ngModelChange that might be a number or a string. Full compiler output:

projects/ngx-nitro-services/src/lib/components/entity/ssin-number-input/ssin-number-input.component.html:6:25 - error TS2322: Type 'string | number' is not assignable to type 'string | undefined'.
  Type 'number' is not assignable to type 'string'.

6            [(ngModel)]="value"
                          ~~~~~~
7            (ngModelChange)="onNumberChange($event)"
  ~~~~~~

  projects/ngx-nitro-services/src/lib/components/entity/ssin-number-input/ssin-number-input.component.ts:12:16
    12   templateUrl: './ssin-number-input.component.html',
                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component SsinNumberInputComponent.
projects/ngx-nitro-services/src/lib/components/entity/ssin-number-input/ssin-number-input.component.html:7:44 - error TS2345: Argument of type 'string | number' is not assignable to parameter of type 'string | undefined'.

7            (ngModelChange)="onNumberChange($event)"
                                             ~~~~~~

  projects/ngx-nitro-services/src/lib/components/entity/ssin-number-input/ssin-number-input.component.ts:12:16
    12   templateUrl: './ssin-number-input.component.html',
                      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    Error occurs in the template of component SsinNumberInputComponent.

Environment

linux, angular 16, primeng 16 rc2, node 16.14

Reproducer

No response

Angular version

16

PrimeNG version

16 rc2

Build / Runtime

Angular CLI App

Language

TypeScript

Node version (for AoT issues node --version)

16.14

Browser(s)

none

Steps to reproduce the behavior

Expected behavior

Templates compiles, runtime value is only string | undefined

Actual behaviour:

Template does not compile because directive declares it might emits numbers.

cghislai commented 1 year ago

see https://github.com/primefaces/primeng/blob/229bb9420fcf7f406e314984a7f064e33640e71f/src/app/components/keyfilter/keyfilter.ts#L105

cghislai commented 1 year ago

My prefered fix would be to only emits string. Regex are intuitively applicable to values of type strings, not numbers.

Some might want to bind number values to input fields of type=number, for instance (although it might be converted back to string by angular iirc). If this use case needs to be supported, maybe the directive could emit another event to not interfere with ngModel.

tbertran commented 11 months ago

I think this bug should be given a high priority since it's a breaking change and, at least for us, makes the directive unusable. I can't think of a valid argument for requiring the model property be of type string | number when the directive's only function is to apply regex filtering.

tarockx commented 2 weeks ago

Has a fix ever been released or a workaround found for this issue? I've just upgraded from PrimeNG 15 to PrimeNG 16 and all my inputs that use regex validation are broken...