Coder Social home page Coder Social logo

Comments (8)

LukasMachetanz avatar LukasMachetanz commented on August 17, 2024 1

@kfrancois, I guess this could be connected to #637.

from spectator.

kfrancois avatar kfrancois commented on August 17, 2024

@LukasMachetanz thank you for logging this issue!

Before we can work on this issue, could you provide some more information around the expected/current behaviour, or perhaps a reproduction?

I've tried the example you mentioned, and I'm not sure what should change around the current behaviour.

Note that this commit addressed input signals with transform: 8cacdda#diff-3d128bff012b5140680c3a116bbeaceaa9721628c0e1ac71b672330a8b30dad0R11

In your example, input.required<number, string> would mean that if one were to pass an id into createComponent({ props: { id } }), the type of id is number | undefined, not string | number | undefined.

At the moment, this is a conscious choice (see discussion here #649). If you believe this is wrong, we can re-open the discussion around this.

I hope this helps already!

from spectator.

LukasMachetanz avatar LukasMachetanz commented on August 17, 2024

@kfrancois, thank you for the fast reply.


Let's assume having the following component:

import { ChangeDetectionStrategy, Component, input, numberAttribute } from "@angular/core";

@Component({
  selector: "pui-some",
  template: "SomeComponent",
  changeDetection: ChangeDetectionStrategy.OnPush,
  standalone: true
})
export class SomeComponent {
  public id = input.required<number, number | string>({ transform: numberAttribute });
}

And let's assume having the following test:

import { createComponentFactory } from "@ngneat/spectator";
import { SomeComponent } from "./some.component";

describe("SomeComponent", () => {
  const createComponent = createComponentFactory({
    component: SomeComponent
  });

  it("renders the component", () => {
    // TS2322: Type string is not assignable to type number
    const spectator = createComponent({ props: { id: "1" } });

    expect(spectator.component).toBeInstanceOf(SomeComponent);
  });
});

I would assume that it is possible to provide "1" as an input to id. Using the component within an template would allow <pui-some id="1" /> and <pui-some [id]="1" /> as well.

Therefore, I am wondering if I am understanding something wrong or if the behaviour within the test is really by intention?

Any help appreciated. :)

from spectator.

LukasMachetanz avatar LukasMachetanz commented on August 17, 2024

@kfrancois, do you have any opinion on this?

from spectator.

kfrancois avatar kfrancois commented on August 17, 2024

@LukasMachetanz sorry for my slow response here - my personal opinion is that the current behaviour makes sense in most cases, as we'd want to pass in the type that the component actually uses (rather than the type that the transform function will accept).

My reasoning here is:

  • Transform functions should be unit tested separately
  • When testing a component, you want to be testing the component itself, not any transform functions its inputs might use

However, I understand that my opinion might not be universally applicable. As such, we could make the typing of InferInputSignal weaker to allow your proposal (basically by flipping <infer K, infer _> to <infer _, infer K>).

If we were to make this change, the drawback is that in the following example:

public id = input.required({ transform: numberAttribute });

The inferred type for id is InputSignalWithTransform<number, unknown> meaning that we'll accept unknown as an input for id. Personally, I think this is a worse API (see reasoning above) but if the general sentiment leans the other way, this can definitely be changed!

from spectator.

LukasMachetanz avatar LukasMachetanz commented on August 17, 2024

@kfrancois, thank you for responding and sharing your opinion. I fear that I see this differently though. I would expect to test against the public interface of SomeComponent, hence to provide id as a number or as a string. A user of the mentioned component could do the same within the template after all. Additionally, I would not like to be forced to make the transform function public due to the test. In my opinion this is an implementation detail of the component itself.

Regarding the inferred type: In my opinion the inferred type should be the accepted type of the transform function. In the case of numberAttribute it would be unknown, but for a custom transform function it could be properly typed. Therefore this is no problem from my point of view. I would totally expect this.

from spectator.

LukasMachetanz avatar LukasMachetanz commented on August 17, 2024

@kfrancois, do you have a final take on this? :)

from spectator.

kfrancois avatar kfrancois commented on August 17, 2024

Sorry @LukasMachetanz, I thought I responded to this already - I can agree with your reasoning, would you like to drop a PR which swaps the generic type for this?

I believe the change should just consist of this:

export type InferInputSignal<T> = T extends InputSignalWithTransform<infer _, infer K> ? K : T;

Thank you, and sorry again for taking so long to get back to you!

from spectator.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.