You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Is your feature request related to a problem? Please describe.
Angular has added a new developer-preview feature for inputs, the new way allows for easier reactive code, and follows the Signal pattern.
syntax for a single member input is class MyComponentWithInput{ myInput = input<string>("value") }
Since the new way changes the class field type from number to InputSignal<number> , StoryObj expects us to provide args of type InputSignal but angular wants a string
Given a component like
import{Component,Input,InputSignal,computed,input}from'@angular/core';functioncoerceBoolean(val: any): boolean{return!!val}
@Component({ ... })exportclassMyTestComponent{name=input<string>("name");// new way for firstName
@Input()lastName: string="lastName";// old way for lastName, we can mix and match old and new// the second accepted generic type defines the input type for the transformer functionsuspended=input<boolean,string>(true,{transform: coerceBoolean});/** Input with its full typing */counter: InputSignal<number>=input(5);/** This field must be set by it's alias when value is provided */fieldWithAlias=input<string>("my alias is foo",{alias: "foo"});// Reactive computed valuereadonlygreeting=computed(()=>'Hello '+this.name()+" "+this.lastName);}
Id like type Story = StoryObj<MyTestComponent>; to adapt the component signal inputs to be their generic type
Bonus request: is there a way to also handle the alias with Typescript types?
Describe the solution you'd like
I've had some success with a adating the component before passing it to StoryObj<>
The type SignalInputCmp<> accepts any object and maps over each fields of type InputSignal to inferred their generic type.
// Extract the generic type from InputSignaltypeInferInputSignalType<P>=PextendsInputSignal<infer T> ?
T : // is Signal, return the first generic typePextendsInputSignal<infer T, infer C> ? C : // Signal has transformer, return the second generic typenever;// Go over every member and convert any InputSignal field to their accepted generic.typeSignalInputCmp<TextendsRecord<string,any>>={[keyinkeyofT]: T[key]extendsInputSignal<any> ?
InferInputSignalType<T[key]> : // infer typeT[key]// is not a Signal, return raw type}
Used like
exportdefaultmeta;typeadaptedComponent=SignalInputCmp<MyTestComponent>;typeStory=StoryObj<adaptedComponent>;exportconstPrimary: Story={args: {name: "salt",lastName: "pepper",suspended: "false",fieldWithAlias: "this field name is not used, we must use the alias name 'foo'"},};exportconstAlt: Story={args: {foo: "alias is respected but type Story still uses field name 'fieldWithAlias'"}asany,// have to cast to `any` so i can use the alias `foo`};
Describe alternatives you've considered
No response
Are you able to assist to bring the feature to reality?
no
Additional context
The provided code examples work with Angular 17.1.1
It's missing support for two of the Angular input features.
valentinpalkovic
changed the title
[Feature Request]: Angular & Typescript: Update StoryObj to handle new InputSignal
[Bug]: Angular & Typescript: Update StoryObj to handle new InputSignal
Jan 28, 2024
FYI - i tried your workaround. You mentioned this does not work for "input.required" and "input alias" . I am able to report that your solution does work with angular 17.2.
i only had to adjust your solution a tiny bit:
typeInferInputSignalType<P>=PextendsInputSignal<infer T> ?
T :
PextendsInputSignalWithTransform<infer T, infer C> ? C : // This line changed !!!never;
Discussed in #25781
Originally posted by boblelot January 28, 2024
Is your feature request related to a problem? Please describe.
Angular has added a new developer-preview feature for inputs, the new way allows for easier reactive code, and follows the Signal pattern.
syntax for a single member input is
class MyComponentWithInput{ myInput = input<string>("value") }
https://angular.io/api/core/InputSignal
Since the new way changes the class field type from
number
toInputSignal<number>
, StoryObj expects us to provide args of typeInputSignal
but angular wants astring
Given a component like
Id like
type Story = StoryObj<MyTestComponent>;
to adapt the component signal inputs to be their generic typeBonus request: is there a way to also handle the alias with Typescript types?
Describe the solution you'd like
I've had some success with a adating the component before passing it to
StoryObj<>
The type
SignalInputCmp<>
accepts any object and maps over each fields of type InputSignal to inferred their generic type.Used like
Describe alternatives you've considered
No response
Are you able to assist to bring the feature to reality?
no
Additional context
The provided code examples work with Angular 17.1.1
It's missing support for two of the Angular input features.
required
:input.required<number>();
alias
:input(0,{alias:"foo"})
https://angular.io/api/core/Input
The text was updated successfully, but these errors were encountered: