TypeScript: 奥深いエラーメッセージを読み解く!'new' expression, whose target lacks a construct signature'エラーの背景にある型システムの仕組み
TypeScriptにおける「'new' expression, whose target lacks a construct signature」エラーのわかりやすい解説
より具体的には、以下の状況でこのエラーが発生します。
- クラスではなく、関数やインターフェースなどを
new
演算子のターゲットに指定している - クラスが存在するが、コンストラクタが定義されていない
- クラスのコンストラクタが、引数や戻り値の型が正しく定義されていない
このエラーを解決するには、以下のいずれかの方法を試すことができます。
正しいクラスを new 演算子のターゲットとして指定する
// 正しい例
const myObject = new MyClass();
// 間違った例
const myObject = new SomeFunction(); // SomeFunctionはクラスではない
const myObject = new MyInterface(); // MyInterfaceはインターフェースである
クラスにコンストラクタを定義する
class MyClass {
// コンストラクタを定義
constructor(public name: string) {}
}
const myObject = new MyClass('Taro');
class MyClass {
// コンストラクタの型を定義
constructor(public name: string, public age: number) {}
}
const myObject = new MyClass('Taro', 30); // 引数と戻り値の型が一致していない
- 上記の解決策以外にも、状況によっては他の方法で解決できる場合があります。詳細については、TypeScriptのドキュメントを参照してください。
- TypeScriptは、静的型付け言語であるため、コンパイル時に型チェックが行われます。このエラーメッセージは、型チェックによって検出された問題を知らせるものです。
class Person {
constructor(public name: string, public age: number) {}
}
const person1 = new Person('Taro', 30); // 正しい例
const person2 = new SomeFunction(); // 間違った例
const person3 = new MyInterface(); // 間違った例
class Car {
// コンストラクタを定義していない
}
const car1 = new Car(); // エラーが発生
class Bike {
// コンストラクタの型が間違っている
constructor(public name: number) {}
}
const bike1 = new Bike('Taro'); // エラーが発生
このコード例では、以下のエラーが発生します。
- 例3
Bike
クラスのコンストラクタの引数の型が間違っているため、エラーが発生します。 - 例2
Car
クラスにはコンストラクタが定義されていないため、エラーが発生します。 - 例1
person2
とperson3
のnew
演算子のターゲットは、クラスではないため、エラーが発生します。
型アサーションを使用すると、TypeScriptコンパイラに、特定の式の型を明示的に伝えることができます。 これにより、コンパイラがエラーを検出するのを防ぐことができます。
// 型アサーションを使用する
const myObject = new (MyFunction as any)('Taro', 30);
// MyFunctionは実際にはクラスではない
function MyFunction(name: string, age: number) {}
ジェネリック型を使用する
ジェネリック型を使用すると、コンストラクタの引数や戻り値の型を動的に指定することができます。 これにより、さまざまなタイプのオブジェクトを作成するために同じコードを使用することができます。
// ジェネリック型を使用する
class GenericClass<T> {
constructor(public value: T) {}
}
const myObject1 = new GenericClass<string>('Taro');
const myObject2 = new GenericClass<number>(30);
any 型を使用する
any
型は、任意の型の値を格納できる特殊な型です。 これは、型チェックを回避するために使用することができますが、非推奨 です。
// 非推奨: 型チェックを回避するために `any` 型を使用する
const myObject = new (any as any)('Taro', 30);
外部ライブラリを使用する
TypeScriptには、new
演算子を使用するコードをより簡単に書くための外部ライブラリがいくつかあります。 例えば、ts-new
ライブラリを使用すると、型アサーションやジェネリック型を使用せずに、安全に new
演算子を使用することができます。
注意事項
- できる限り、正しい型を定義してコードを書く ようにしてください。
- 型チェックを回避することは、コードの品質を低下させる可能性 があります。
- 上記の方法は、あくまでも一時的な解決策 として使用してください。
javascript typescript