【Angular エラー解決ガイド】EventEmitter エラー「Expected 0 type arguments, but got 1」をステップバイステップで解決
Angular EventEmitter エラー: 期待される型引数が 0 件なのに 1 件見つかりました
このエラーは、Angular コンポーネント間の通信に使用される EventEmitter
を使用しているときに発生します。エラーメッセージは、EventEmitter
に渡される引数の数が期待される数と一致していないことを示しています。
原因
このエラーは、以下のいずれかの原因で発生する可能性があります。
- 子コンポーネントから親コンポーネントに渡されるイベントデータの型が間違っている。
解決策
このエラーを解決するには、以下の手順を実行します。
引数の数をチェックする
親コンポーネントから子コンポーネントに渡される引数の数が、子コンポーネントの
@Input
デコレータで指定された引数の数と一致していることを確認します。
例
以下の例では、親コンポーネント app-parent
から子コンポーネント app-child
に message
という名前のプロパティが渡されます。
// app-parent.component.ts
@Component({
selector: 'app-parent',
template: `
<app-child [message]="'Hello from parent!'"></app-child>
`,
})
export class AppParentComponent {
}
// app-child.component.ts
@Component({
selector: 'app-child',
template: `
<p>{{ message }}</p>
`,
})
export class AppChildComponent {
@Input() message: string;
}
この場合、app-child
コンポーネントの @Input
デコレータで message
プロパティの型が string
と指定されているため、親コンポーネントから渡される 'Hello from parent!'
という文字列は問題ありません。
しかし、もし app-child
コンポーネントの @Input
デコレータで message
プロパティの型が number
と指定されていた場合、以下のエラーが発生します。
ERROR in app-child.component.ts
2:17
'message' is not assignable to parameter of type 'number'.
Type 'string' is not assignable to type 'number'.
これは、親コンポーネントから渡される 'Hello from parent!'
という文字列が number
型ではないためです。このエラーを解決するには、親コンポーネントから渡される文字列を数値に変換するか、app-child
コンポーネントの @Input
デコレータで message
プロパティの型を string
に変更する必要があります。
- Angular DevTools を使用すると、エラーの原因をより簡単に特定することができます。
- TypeScript コンパイラの設定で
strict
オプションを有効にすると、このような型エラーをより早く検出することができます。
// 親コンポーネント
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-root',
template: `
<app-child [message]="message"></app-child>
<button (click)="sendMessage()">送信</button>
`
})
export class AppComponent implements OnInit {
message = 'こんにちは!';
constructor() {}
ngOnInit(): void {}
sendMessage() {
// 親コンポーネントから子コンポーネントへメッセージを送信
this.message = 'Angular から TypeScript へようこそ!';
}
}
// 子コンポーネント
import { Component, Input, Output, EventEmitter } from '@angular/core';
@Component({
selector: 'app-child',
template: `
<p>{{ message }}</p>
`
})
export class ChildComponent {
@Input() message: string;
@Output() messageChange = new EventEmitter<string>();
constructor() {}
onChange() {
// 子コンポーネントから親コンポーネントへメッセージ変更イベントを発行
this.messageChange.emit('メッセージが変更されました!');
}
}
このコードで発生する問題
このコードを実行すると、コンソールに以下のエラーが表示されます。
ERROR in app.child.component.ts
2:17
'messageChange' is not assignable to parameter of type 'EventEmitter<number>'.
Type 'EventEmitter<string>' is not assignable to type 'EventEmitter<number>'.
このエラーは、app.child.component.ts
ファイルの messageChange
プロパティの型が EventEmitter<number>
と宣言されているため発生します。しかし、親コンポーネント app.component.ts
から子コンポーネント app.child.component.ts
へ渡される message
プロパティの型は string
です。
エラーの解決
方法 1:messageChange
プロパティの型を string
に変更する
// app.child.component.ts
@Component({
selector: 'app-child',
template: `
<p>{{ message }}</p>
`
})
export class ChildComponent {
@Input() message: string;
@Output() messageChange = new EventEmitter<string>(); // 型を 'string' に変更
constructor() {}
onChange() {
this.messageChange.emit('メッセージが変更されました!');
}
}
方法 2:sendMessage
関数で渡されるメッセージの型を number
に変換する
// app.component.ts
sendMessage() {
// 親コンポーネントから子コンポーネントへメッセージを送信
this.message = parseInt(this.message, 10); // メッセージを数値に変換
}
修正後
上記いずれかの方法で修正後、エラーは発生しなくなります。
方法 3:ジェネリック型を使用する
EventEmitter
はジェネリック型であるため、イベントデータの型を明示的に指定することができます。
// app.child.component.ts
@Component({
selector: 'app-child',
template: `
<p>{{ message }}</p>
`
})
export class ChildComponent {
@Input() message: string;
@Output() messageChange = new EventEmitter<string>(); // 型を明示的に指定
constructor() {}
onChange() {
this.messageChange.emit('メッセージが変更されました!');
}
}
方法 4:as
キーワードを使用する
as
キーワードを使用して、渡されるデータ型を明示的に指定することができます。
// app.component.ts
sendMessage() {
// 親コンポーネントから子コンポーネントへメッセージを送信
this.messageChange.emit(this.message as string); // 'as string' を使用して型を明示的に指定
}
angular typescript parent-child