我不知道如何恰当地描述这个,所以让我想出一个例子。我有一个库,它返回一个用作构造函数的函数:
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;
}
基本上我想以某种方式定义声明实际用户的代码在哪里。根据我对环境声明的理解,它们被指定为“其他地方”。我无法弄清楚这个“其他地方”到底在哪里。我检查了typescript examples之一,但是我没有看到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();
用户对象包含任何mongoose为您提供的继承属性(我已将其映射到MongooseBase
定义)。它还为您提供了作为初始模式创建的一部分传入的属性(当我定义user
时)。
我希望能够强烈输入此代理,例如
var user:UserData = new schema.UserData();
如果我这样做,那么打字稿编译器会因以下异常而崩溃,导致我相信我正在做一些疯狂的事情而且可能不对:
\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)
所以我设置它的方式我没有在webstorm中得到任何错误,并且生成的其他文件的代码确实正常工作(它匹配我自己编写的javascript),但是typescript编译器崩溃了不会更新我使用引用的文件。
答案 0 :(得分:3)
看起来你想在你的库中声明你的库和构造函数(建模为下面的类)。这是你在找什么?
declare module lib {
export class User {
name: string;
age: number;
getChildren(): User[];
}
}
var userTemplate = lib.User;
var user = new userTemplate();
user.name = "dave";
通常,您的库声明将在您引用的.d.ts文件中。
如果我理解你的问题,请告诉我。
行。我对Mongoose不熟悉,但让我看看我是否正确理解(快速查看http://mongoosejs.com/docs/index.html后)
这很有趣,因为Schema归结为结构类型大纲,类似于TypeScript中的接口,以类似JSON的语法指定,传递主要构造函数来指定类型(Number,String,Date等... )。但是,由于TypeScript类型纯粹是在发出的JavaScript中不存在的注释,因此您无法重用它们(并且它们具有不同的类型,如ObjectID)。
一旦我们使用该语言获得泛型,我们就会有更聪明的方法来执行此操作并通过查找,保存等方式流式传输文档类型......但下面是我认为当前键入此内容的最简单方法。这与你追求的更加一致吗?
// Let's type it as any for now
declare var mongoose: any;
// Base interface that any 'document' will have
interface mongooseBase {
find: (callback: { (err: any, items: any[]): void; }) => void;
save: (hanlder: { (err: any): void; }) => void;
}
// This is the structure our 'person' document will have
interface person extends mongooseBase {
name: string;
age: number;
children: { name: string; dependent: bool; }[];
};
// Need to provide the same structure in 'mongoose' style format to define.
var personSchema = mongoose.Schema({ name: String, age: Number, children: [{ name: String, dependent: Boolean }] });
// Get back a constructor function. We assert that the type returned is a 'newable' Function (a constructor), and will return a 'person' type when called
var Person = <{ new (): person; }>mongoose.model('Person', personSchema);
// Let's create one
var p1 = new Person();
// Let's set a property
p1.name = "Dave";
// Let's save Dave
p1.save(function (err) { /*TODO*/ });