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

model() should support a narrower output type #55754

Open
Harpush opened this issue May 10, 2024 · 6 comments
Open

model() should support a narrower output type #55754

Harpush opened this issue May 10, 2024 · 6 comments
Labels
area: core Issues related to the framework runtime core: inputs / outputs cross-cutting: signals feature Issue that requests a new feature
Milestone

Comments

@Harpush
Copy link

Harpush commented May 10, 2024

Which @angular/* package(s) are relevant/related to the feature request?

core

Description

Currently input supports transform but model doesn't although it can be very handy.

Proposed solution

Allow model(2, {transform: fn})
For example if I can accept number | '${number}' from outside but emit only number.
It allows the user to either use:

  1. modelName="8" without two way binding
  2. [(modelName)]="value" with two way binding while value is only number

Alternatives considered

Probably use model<number | '${number}'>(2). But then inside I need to run the transform function myself

@alxhub
Copy link
Member

alxhub commented May 10, 2024

This is a duplicate of #55166 which has the previous discussion (which concluded that model() should not support transform).

@alxhub alxhub changed the title Signal model with transform like input model() should support a narrower output type May 10, 2024
@alxhub
Copy link
Member

alxhub commented May 10, 2024

I'm going to steal this issue and refocus it a bit. transform support isn't necessary to address the problem you're talking about. If we had a way to declare that model() will emit a narrower type than it accepts, then it could support two-way binding to a WritableSignal<number> since Signal<number> is assignable to Signal<number|string> and we'd never try to write a string back.

@alxhub alxhub added feature Issue that requests a new feature area: core Issues related to the framework runtime core: inputs / outputs core: reactivity Work related to fine-grained reactivity in the core framework cross-cutting: signals labels May 10, 2024
@ngbot ngbot bot added this to the Backlog milestone May 10, 2024
@alxhub alxhub removed the core: reactivity Work related to fine-grained reactivity in the core framework label May 10, 2024
@Harpush
Copy link
Author

Harpush commented May 10, 2024

I'm going to steal this issue and refocus it a bit. transform support isn't necessary to address the problem you're talking about. If we had a way to declare that model() will emit a narrower type than it accepts, then it could support two-way binding to a WritableSignal<number> since Signal<number> is assignable to Signal<number|string> and we'd never try to write a string back.

But how would you transform the string to the number for input values? At the end the component internally only want number and will always emit number. Only the outside can provide strings.

@alxhub
Copy link
Member

alxhub commented May 11, 2024

But how would you transform the string to the number for input values? At the end the component internally only want number and will always emit number. Only the outside can provide strings.

You can use a computed to go from number|string to just number.

@Harpush
Copy link
Author

Harpush commented May 11, 2024

But how would you transform the string to the number for input values? At the end the component internally only want number and will always emit number. Only the outside can provide strings.

You can use a computed to go from number|string to just number.

But wouldn't something like model(2, {inputTansform: fn}) makes more sense? Especially if we look at it as input and output - a model built from input with transform and output with actual type. The output type must be assigned to the input type.

@Harpush
Copy link
Author

Harpush commented May 17, 2024

@alxhub Just adding that using input and output we can do:

value = input(2, { transform: fn });
valueChange = output<number>();

The only downside is we can't change it from inside and the outside must implement the output and input or two way binding.
Hence the suggested:

value = model(2, {inputTansform: fn});

Which does exactly the same but with model added features.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: core Issues related to the framework runtime core: inputs / outputs cross-cutting: signals feature Issue that requests a new feature
Projects
None yet
Development

No branches or pull requests

2 participants