Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bug(cdk/coercion): coerceNumberProperty(thing, undefined) has invalid implementation or signature #29425

Closed
1 task
urugator opened this issue Jul 11, 2024 · 8 comments · Fixed by #29491
Closed
1 task
Labels
area: cdk/coercion P4 A relatively minor issue that is not relevant to core functions

Comments

@urugator
Copy link

Is this a regression?

  • Yes, this behavior used to work in the previous version

The previous version in which this bug was not present was

No response

Description

coerceNumberProperty(thing, undefined) works the same way as coerceNumberProperty(thing), so it yields 0 if the thing isn't coercible to number. This is quite unexpected, because:

  1. In all other cases the fallback argument is respected.
  2. The return type is different: coerceNumberProperty(thing, undefined) returns number | undefined, even though the implementation always yields number.

Reproduction

StackBlitz link:
Steps to reproduce:
1.
2.

Expected Behavior

Fallback argument should be respected even for undefined.

Actual Behavior

undefined isn't respected as a fallback.

Environment

  • Angular: 17.0.6
  • CDK/Material: 17.1.0
  • Browser(s): *
  • Operating System (e.g. Windows, macOS, Ubuntu): *
@urugator urugator added the needs triage This issue needs to be triaged by the team label Jul 11, 2024
@crisbeto crisbeto added P4 A relatively minor issue that is not relevant to core functions area: cdk/coercion and removed needs triage This issue needs to be triaged by the team labels Jul 12, 2024
@GiftLanga
Copy link
Contributor

I'll work on this issue if no one working on it.

@GiftLanga
Copy link
Contributor

@urugator it's not possible to set the fallback value as undefined as you can see on the implementation the default fallback value is 0.
image

I suggest that you return a string as a work around like this.
coerceNumberProperty<String>(value, 'undefined')

@urugator
Copy link
Author

the implementation the default fallback value is 0.

Yes and the issue states that the implementation or signature is not correct.
Either the implementation should check arguments.length or the return type of coerceNumberProperty(x,undefined) should resolve to number. Instead it matches coerceNumberProperty<D>(value: any, fallback: D): number | D overload, so the return type resolves to number | undefined, which makes you believe it returns undefined when value is not coercible to number. I am just repeating what is already noted in the OP.

@GiftLanga
Copy link
Contributor

It is correct that the return type of coerceNumberProperty(x,undefined) is number | undefined because of this definition coerceNumberProperty<D>(value: any, fallback: D): number | D as you stated.

However as I said it is not possible to return undefined when the fallback default value is 0. The only way I can think of is to set the fallback default value to undefined, but that will break the tests.

A better recommendation would be to use null instead, because it's an assignment value.
coerceNumberProperty(value, null)

@urugator
Copy link
Author

it is not possible to return undefined when the fallback default value is 0.

export function coerceNumberProperty(value: any, fallbackValue: any) {
  return _isNumberValue(value) ? Number(value) : arguments.length === 2 ? fallbackValue : 0;
}
// coerceNumberProperty('foo') === 0
// coerceNumberProperty('foo', undefined) === undefined

Note that implementation signature is not visible from the outside, so this doesn't break the API, quite the opposite - the implementation is changed to match these 2 overload signatures, that are actually visible from the outside.

@GiftLanga
Copy link
Contributor

Ohh okay I see, can you make the PR.

GiftLanga added a commit to GiftLanga/angular-components that referenced this issue Jul 26, 2024
Returns undefined when the fallback argument is undefined
for cases where the value is not a number

Fixes angular#29425
GiftLanga added a commit to GiftLanga/angular-components that referenced this issue Jul 26, 2024
Returns undefined when the fallback argument is undefined
for cases where the value is not a number

Fixes angular#29425
crisbeto pushed a commit that referenced this issue Jul 29, 2024
…ned (#29491)

Returns undefined when the fallback argument is undefined
for cases where the value is not a number

Fixes #29425

(cherry picked from commit c9078d1)
@urugator
Copy link
Author

@crisbeto Thank you for picking this up, but I think you forgot to remove the default value in argument fallbackValue = 0 => fallbackValue. JS treats undefined as not provided:

function foo(x=0) {
    console.log(arguments.length, x);
}
foo(); // 0 0
foo(undefined); // yields 1 0  but we want 1 undefined

@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Aug 31, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: cdk/coercion P4 A relatively minor issue that is not relevant to core functions
Projects
None yet
3 participants