打字稿类,接口和泛型

时间:2017-04-28 09:32:35

标签: typescript

我正在编写2个课程ProjectUser,每个课程都有find方法,需要拨打api休息电话

尝试#1

class Project {
  find(params) { 
    return request({url: "/api/Project", qs: params});
  }
}

class User {
  find(params) { 
    return request({url: "/api/User", qs: params});
  }
}

现在,这显然不是很好;)没有检查参数,没有定义类型,重复代码等等

尝试#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"); }    
}

所以,稍好一些。代码重复较少。仍然没有类型检查。与救援接口;)

尝试#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"); }    
}

这是我开始遇到一些问题的地方。 Project和User api params对象都需要token属性。但是,它们还需要设置userDdprojectId

目前,我需要将这两者添加到IParams界面,这似乎是错误的。

尝试#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"); }    
}

但是,这没有帮助:因为Base类定义了find方法,编译器如何验证用户useridtoken是否也被传递 - < em>没有传递其他参数,同样也适用于项目

这也促使我考虑find方法的返回值:对于我想要一组IPromiseModel的项目,对于用户,IUserModel

我已经尝试过将IProject界面改为阅读

interface IProject {
    find(params:IProjectParams):Promise<IProjectModel[]>
}

但我仍然可以将任何属性传递到params - 即我可以做

Project.find({token: "1234",foobar:true})

我怀疑这是因为我没有为Base find

中的参数定义类型

知道泛型必须参与其中,但对于我的生活,我无法得到符合这些要求的定义

我正在使用typescript 2.2.2

1 个答案:

答案 0 :(得分:2)

使用泛型,你可以这样做:

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'
});

此处的基类TParams extends IParams中的约束是可选的,因为您没有显式访问令牌属性。