In an angular 15 project, I have a component called in the html file by
<app-component
(onAction)="action($event)">
</app-component>
and the invoked action function declared in the ts file as
action(event: { first_data_item: number; second_data_item: number; third_data_item: any; fourth_data_item: string }) {}
If enabling strict mode, I get error
Argument of type 'Object' is not assignable to parameter of type '{ first_data_item: number; second_data_item: number; third_data_item: any; fourth_data_item: string }'.
Without strict mode enabled, this works like a charm.
How should I specify the data sent with this function call?
CodePudding user response:
The type of your function argument definition and your $event
parameter must match.
We can't see how you have defined your @Output() onAction
in your app.component.ts
but my guess is it is something generic like:
@Output() onAction: {};
Therefore TypeScript complains that onAction
may be emitting an object with any keys/values and your consuming action()
function is expecting specific keys/values, specifically:
{
first_data_item: number;
second_data_item: number;
third_data_item: any;
fourth_data_item: string
}
To resolve this specific clash in isolation you have two options:
- Change your
onAction
type to match youraction
type, i.e. makeonAction
more specific - Change your
action()
type to match youronAction
type, i.e. makeaction()
less specific
However, I assume from the term action
you are trying to build a state management solution and have therefore intentionally loosely typed onAction
and specifically typed action
as you are expecting to have multiple actions with different payloads (objects). Therefore neither of the above solutions will work for you.
A better way of doing this would be to leverage discriminated union types
actions.ts
type ActionOne = {
type: 'actionOne',
payload: {
first_data_item: number;
second_data_item: number;
third_data_item: any;
fourth_data_item: string
}
}
type ActionTwo = {
type: 'actionTwo',
payload: {
someOtherKey: any
}
}
type Actions = ActionOne | ActionTwo
app.component.ts
@Output() onAction: Actions;
other.component.html
<app-component
(onAction)="action($event)">
</app-component>
other.component.ts
action(event: Actions) {
if (event.type === 'actionOne') {
// It knows the type of payload is ActionOne['payload']
event.payload.first_data_item // valid
event.payload.someOtherKey // error
}
else {
// It knows the type of payload is ActionTwo['payload']
event.payload.first_data_item // error
event.payload.someOtherKey // valid
}
}