はじめに
Angular + TypeScriptでcanvasの処理を書いていたら、下記のエラーが発生しました(3つとも同様のエラー)。
ERROR in src/app/app.component.ts(159,7): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'string | boolean' has no compatible call signatures. src/app/app.component.ts(178,5): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'string | boolean' has no compatible call signatures. src/app/app.component.ts(183,5): error TS2349: Cannot invoke an expression whose type lacks a call signature. Type 'string | boolean' has no compatible call signatures.
開発環境
Angular@5.2.0
TypeScript@2.5.3
VisualStudioCode@1.20.0
発生したエラーについて
上記エラーは日本語だと下記の通り表示されます。
[ts] 型に呼び出しシグネチャがない式を呼び出すことはできません。型 'string | boolean' には互換性のある呼び出しシグネチャがありません。
エラーが発生した箇所はいずれもHTML5のcanvasから取得したcontextからメソッドを呼び出す箇所で発生しています。
- エラー発生箇所-1
render() { const ctx = this.context; if (ctx) { ctx.clearRect(0, 0, this.canpasWidth, this.canpasHeight); // <- エラー発生 ctx.strokeStyle = 'black';
- エラー発生箇所-2, 3
drawBlock(x: number, y: number) { this.context.fillRect(this.blockWidth * x, this.blockHeight * y, this.blockWidth - 1, this.blockHeight - 1); // <- エラー発生 this.context.strokeRect(this.blockWidth * x, this.blockHeight * y, this.blockWidth - 1, this.blockHeight - 1); // <- エラー発生 }
エラー原因
canvasから取得したcontextの型を誤まってCanvas2DContextAttributes
にしたのが原因でした。
- 修正前のコード
export class AppComponent implements AfterViewInit { context: Canvas2DContextAttributes; // <- エラー原因 ngAfterViewInit() { const canvas = this.block.nativeElement; this.context = canvas.getContext('2d'); setInterval(() => this.render(), 30); } }
contextの型をCanvasRenderingContext2D
に修正したところエラーが全部消えて正しく稼働しました。
- 修正後のコード
export class AppComponent implements AfterViewInit { context: CanvasRenderingContext2D; // <- CanvasRenderingContext2Dに修正するとエラーが消える ngAfterViewInit() { const canvas = this.block.nativeElement; this.context = canvas.getContext('2d'); setInterval(() => this.render(), 30); } }