[英]typescript classes, interfaces and generics
I am writing 2 classes, Project
and User
, each of which has a find
method that needs to call an api rest call 我正在编写
Project
和User
这两个类,每个类都有一个find
方法,需要调用api rest调用
attempt #1 尝试#1
class Project {
find(params) {
return request({url: "/api/Project", qs: params});
}
}
class User {
find(params) {
return request({url: "/api/User", qs: params});
}
}
now, this is obviously not very good ;) There are no checks on the parameters, no types defined, duplicate code etc etc 现在,这显然不是很好;)没有检查参数,没有定义类型,重复代码等
attempt #2 尝试#2
class Base {
constructor(private name:string) {
}
find(options) {
return request({url: `/api/${this.name}`, qs: params});
}
}
class Project extends Base{
constructor() { super("Project"); }
}
class User {
constructor() { super("User"); }
}
so, slightly better. 因此,略胜一筹。 less code duplication.
减少代码重复。 Still no type checking.
仍然没有类型检查。 Interfaces to the rescue ;)
救援接口;)
attempt#3 尝试#3
interface IParams { token: string }
class Base {
constructor(private name:string) {
}
find(params:IParams) {
return request({url: `/api/${this.name}`, qs: params});
}
}
class Project extends Base{
constructor() { super("Project"); }
}
class User extends Base {
constructor() { super("User"); }
}
this is where I started to hit some problems. 这是我开始遇到一些问题的地方。 The Project and User api params object both require the
token
property. Project和User api params对象都需要
token
属性。 However, they also require userDd
and projectId
to be set 但是,它们还需要设置
userDd
和projectId
At the moment, I need to add both of those to the IParams interface, which seems wrong. 目前,我需要将两者都添加到IParams接口中,这似乎是错误的。
attempt#4 尝试#4
interface IUserParams { userid:number, token: string }
interface IProjectParams { projectid:number, token: string }
interface IProject {
find(params:IProjectParams)
}
interface IUser {
find(params:IUserParams)
}
class Base {
constructor(private name:string) {
}
find(params) { // I have no idea on how to "type" params
return request({url: `/api/${this.name}`, qs: params}); // likewise no idea on how to type the return value
}
}
class Project extends Base implements IProject {
constructor() { super("Project"); }
}
class User extends Base implements IUser {
constructor() { super("User"); }
}
However, this does not help : as the Base class defines the find
method, how can the compiler verify that for user, userid
and token
are passed - also, that no other parameter is passed, and likewise for project 但是,这无济于事:因为基类定义了
find
方法,编译器如何才能验证是否为用户, userid
和token
传递了-此外,也没有其他参数传递给项目,同样对于项目也是如此
This also led me onto thinking about the return value of the find
method : for projects I want an array of IPromiseModel
, and for user, IUserModel
这也使我开始思考
find
方法的返回值:对于项目,我需要IPromiseModel
数组,对于用户,则是IUserModel
I have tried chaning the IProject
interface to read 我尝试更改
IProject
接口以读取
interface IProject {
find(params:IProjectParams):Promise<IProjectModel[]>
}
but I still can pass any property into the params
- ie I can do 但我仍然可以将任何属性传递给
params
-即我可以
Project.find({token: "1234",foobar:true})
I suspect this is because I haven't defined a type for the parameter in the Base find 我怀疑这是因为我没有在Base查找中为参数定义类型
I know that generics must play a part in this, but for the life of me I cannot get a definition working that matches these requirements 我知道泛型必须在其中起作用,但是对我而言,我无法获得符合这些要求的定义
I am using typescript 2.2.2 我正在使用打字稿2.2.2
With generics you can do this: 使用泛型,您可以执行以下操作:
interface IParams { token: string }
interface IUserParams { userid:number, token: string }
interface IProjectParams { projectid:number, token: string }
class Base<TEntity, TParams extends IParams> {
constructor(private name:string) {
}
find(params: TParams): Promise<TEntity[]> {
return request({url: `/api/${this.name}`, qs: params});
}
}
class Project extends Base<Project, IProjectParams> {
constructor() { super("Project"); }
}
class User extends Base<User, IUserParams> {
constructor() { super("User"); }
}
new User().find({
userid: 123,
token: 'test'
});
The constraint in the Base class TParams extends IParams
here is optional, since you are not explicitly accessing the token property. 基类
TParams extends IParams
的约束在这里TParams extends IParams
是可选的,因为您没有显式访问令牌属性。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.