以下でEntity
をインポートすると、投稿の件名エラーが発生します(TypeError:ObjectプロトタイプはObjectまたはnull:undefinedの可能性があります)が、インポートを実際のEntity
宣言で置き換えると、コードうまくいきます。
これは Customer.ts
でコードを実行するとエラーが発生する形式でts-node
:
index.ts
export { Customer } from "./Customer";
export { Entity } from "./Entity";
Customer.ts
import { Entity } from "./index";
export class Customer extends Entity {
sku: string;
constructor(po: any) {
super();
this.sku = po.sku;
}
}
Entity.ts
export abstract class Entity {
id?: string;
}
Run.ts(テストコード)
import {Customer} from "./";
let c = new Customer({
name: "Bob"
});
console.log(c);
Entity
インポートを次のような宣言に置き換えると、
export abstract class Entity {
id?: string;
}
export class Customer extends Entity {
sku: string;
constructor(po: any) {
super();
this.sku = po.sku;
}
}
次にRun.ts
これをログに記録します:
Customer { sku: undefined }
つまり、問題なく実行され、エラーは発生しません。考え?
私が疑ったように、元のプログラムには循環インポートがあります。 Run.ts
はindex.ts
をインポートし、Customer.ts
はindex.ts
を再度インポートします。 index.ts
は既に読み込み処理中であり、それ自体がCustomer.ts
に依存しているため、import { Entity } from "./index";
はindex.ts
のEntity
をバインドするだけです(まだ設定されていません) )をCustomer.ts
のEntity
に変更すると、index.ts
の読み込みが完了していなくても実行が続行されます。その場合、Entity
は、拡張しようとした時点では未定義です。循環インポートはエラーになるか、JavaScriptエンジンはシナリオを正しく処理する他のアルゴリズムを使用する必要があると主張するかもしれません。現在のデザインが選ばれた理由についてコメントする資格はありません。 (他の人もこれについての情報を自由に追加してください。)
ご覧のとおり、Customer.ts
を./Entity
ではなく./index
から直接インポートするように変更すると、サイクルが中断され、すべてが期待どおりに機能します。別の解決策は、index.ts
のインポートの順序を逆にすることです。