これを適切に説明する方法がわからなくなったので、例を考えてみましょう。コンストラクターとして使用する関数を返すライブラリがあります。
var userTemplate = lib.User;
var user = new userTemplate();
userTemplate
どのようなプロパティを持つかはわかっているので、これをクラスとして強く型付けしたいと思います。var user = new userTemplate()
アプリケーションの他の部分でも、user
オブジェクトを既知のタイプにすることができるようにしたいと考えています。
ここでアンビエント クラス宣言を使用する必要があるように感じますが、実際のビルダーへの参照をアンビエント宣言に割り当てる方法がわかりません。
たとえば、次のようなものが必要です。
export class Storage{
init(){
// somehow define that when you
// new a User to call this function
User = lib.User;
}
}
declare class User{
public name:string;
}
基本的に、実際のユーザーを宣言するコードがどこにあるかを何らかの形で定義したいと考えています。アンビエント宣言について私が理解していることから、それらは「他の場所」で指定されています。この「他の場所」が実際にどこにあるのかわかりません。タイプスクリプトの例の1つを確認しましたが、mongodbのアンビエント宣言が実際の実装にどのようにマップされているかわかりません。
ここでパズルのピースが欠けているような気がします。
編集(詳細付き)
ここで具体的に説明しましょう。
強いタイプのマングースを使おうとしています。Schema クラスがあるとします。
export class Schema{
public UserData:User;
constructor(){
var mongoose:IMongooseBase = require("mongoose");
var mongooseSchema = <MongooseSchema>mongoose.Schema;
var user = new mongooseSchema({
name: String
});
this.UserData = mongoose.model("User", user);
}
}
export declare class User extends MongooseBase{
constructor(item:any);
public _id: string;
public name: string;
}
declare class MongooseBase {
findOne(item:any, callback:ICallback) : void;
find(id:string, callback?:ICallback) : IChainable;
save(item: IEmptyCallback) : void;
remove(item:any, callback:IErrorCallback) : void;
push(item:MongooseBase):void;
}
interface IMongooseSchema{
ObjectId:String;
}
declare class MongooseSchema implements IMongooseSchema{
constructor(item:any);
public ObjectId:String;
}
interface IMongooseBase{
model(name:String, ref:any):any;
Schema():any;
}
Mongoose のモデル関数は、コンストラクターとして使用する関数を提供します。このオブジェクトを使用して新しいモデル タイプを作成すると、プロパティが定義されMongooseBase
ます (find、findOne など)。また、このユーザーには、アンビエント クラスUser
(名前) で定義されたスキーマの一部として定義されたユーザー プロパティが必要です。
したがって、たとえば、JavaScript では、これは次のようになります。
var userProxy = mongoose.Schema("User", user);
var userData = new userProxy();
ユーザーオブジェクトには、マングースが提供するものから継承されたプロパティが含まれています(MongooseBase
定義にマップしました)。また、最初のスキーマ作成の一部として渡したプロパティも提供します (定義したときuser
)。
このプロキシを次のように強く型付けできるようにしたい
var user:UserData = new schema.UserData();
これを行うと、次の例外で typescript コンパイラがクラッシュし、私は何か非常に奇抜で、おそらく正しくないことをしていると信じるようになります。
\AppData\Roaming\npm\node_modules\typescript\bin\tsc.js:24488
throw err;
^
TypeError: Cannot read property 'construct' of null
at TypeFlow.typeCheckNew (\AppData\Roaming\npm\node_modules\typescript\bin\tsc.js:20675:27)
at CallExpression.typeCheck (\AppData\Roaming\npm\node_modules\typescript\bin\tsc.js:1275:33)
at TypeFlow.typeCheck (\AppData\Roaming\npm\node_modules\typescript\bin\tsc.js:18505:28)
at TypeChecker.typeCheckWithContextualType (\AppData\Roaming\npm\node_modules\typescript\bin\tsc.js:15909:27)
at TypeFlow.typeCheckBoundDecl (\AppData\Roaming\npm\node_modules\typescript\bin\tsc.js:18647:38)
at VarDecl.BoundDecl.typeCheck (\AppData\Roaming\npm\node_modules\typescript\bin\tsc.js:1631:29)
at ASTList.typeCheck (\AppData\Roaming\npm\node_modules\typescript\bin\tsc.js:1016:55)
at TypeFlow.typeCheck (\AppData\Roaming\npm\node_modules\typescript\bin\tsc.js:18505:28)
at TypeFlow.typeCheckFunction (\AppData\Roaming\npm\node_modules\typescript\bin\tsc.js:19815:22)
at FuncDecl.typeCheck (\AppData\Roaming\npm\node_modules\typescript\bin\tsc.js:1783:29)
編集 2
したがって、私がセットアップした方法では、webstorm でエラーは発生せず、他のファイル用に生成されたコードは適切に機能します (それは私が自分で書いた JavaScript と一致します) が、typescript コンパイラはクラッシュし、参照を使用しているファイルを更新しました。