简体   繁体   English

使用 Typescript 泛型类型

[英]Using Typescript generic types

I have an interface that describes basic database CRUD operations like so:我有一个描述基本数据库 CRUD 操作的界面,如下所示:

export interface IUserDB {
  insert: (params: UserAttributes) => Promise<UserResult>
  findById: ({ id }: { id: number }) => Promise<UserResult | null>
  findByEmail: ({ email }: { email: string }) => Promise<UserResult | null>
  remove: ({ id }: { id: number }) => Promise<any>
  update: ({
    id,
    ...changes
  }: { id: number } & UserAttributes) => Promise<UserResult>
}

I then go ahead to use this interface in this manner:然后我在 go 之前以这种方式使用这个接口:

const makeAddUser = ({ usersDb }: { usersDb: IUserDb }) => {
  return async function addUser(userDetails: User) {
    const user = makeUser(userDetails)
    const exists = await usersDb.findByEmail({ email: user.getEmail() })
    if (exists) {
      throw new UniqueConstraintError('Email')
    }
    const newUser = await usersDb.insert({
      name: user.getName(),
      email: user.getEmail(),
      password: user.getPassword(),
      username: user.getUsername(),
    })

    const { id } = newUser.user
    await publisher(id.toString(), 'newuser.verify')
    await consumer('verify_queue', verifyUser, '*.verify')
    return newUser
  }
}

I want to be able to reuse this interface for PostDb and CommentDb without me having to write another interface that describes a Post database operation, how can I achieve this?我希望能够为PostDbCommentDb重用这个接口,而不必编写另一个描述Post数据库操作的接口,我该如何实现呢? I read about Typescript Generics , but I am not really sure how to apply it to this case, any help will be appreciated.我阅读了有关Typescript Generics的信息,但我不确定如何将其应用于此案例,我们将不胜感激。 I am still trying to get a hang of Typescript.我仍在尝试了解 Typescript。 Thank you very much!非常感谢!

Not really sure how to explain it other than to just show you, but here is what I would do (with some filler code to make things work, but just focus on the interfaces).除了向您展示之外,我不确定如何解释它,但这就是我要做的(使用一些填充代码来使事情正常工作,但只关注接口)。 But basically you define an interface, and pass in the types you want it to support inside <>.但基本上你定义一个接口,并在 <> 中传入你希望它支持的类型。 So below I do所以下面我做

export interface IDB<Attributes, Result> {

which means you pass in two additional types to this:这意味着您将另外两种类型传递给此:

interface IUserDb extends IDB<UserAttributes, UserResult>

and now IUserDb is an IDB where any place IDB has Attributes it instead uses UserAttributes , and same with Result and UserResult :现在IUserDb是一个IDB ,其中任何地方IDB都有Attributes它改为使用UserAttributes ,与ResultUserResult相同:

https://codesandbox.io/s/typescript-playground-export-forked-nej0s?file=/index.ts:0-1569 https://codesandbox.io/s/typescript-playground-export-forked-nej0s?file=/index.ts:0-1569

 export interface IDB<Attributes, Result> { insert: (params: Omit<Attributes, 'id'>) => Promise<Result> findById: ({ id }: { id: number }) => Promise<Result | null> remove: ({ id }: { id: number }) => Promise<any> update: ({ id, ...changes }: { id: number } & Attributes) => Promise<Result> } interface UserAttributes { id: string; name: string; username: string; email: string; password: string; } interface UserResult extends UserAttributes { getEmail(): string getName(): string getPassword(): string getUsername(): string } export interface IUserDb extends IDB<UserAttributes, UserResult>{ findByEmail: ({ email }: { email: string }) => Promise<UserResult | null> } const makeUser = (user: UserAttributes): UserResult => { const u: any = {...user }; u.getName = () => u.name; u.getEmail = () => u.email; u.getPassword = () => u.password; u.getUsername = () => u.username; return u as UserResult; } const UniqueConstraintError = (err: string) => new Error(`Unique Constraint Error: ${err}`); const makeAddUser = ({ usersDb }: { usersDb: IUserDb }) => { return async function addUser(userDetails: UserAttributes) { const user = makeUser(userDetails) const exists = await usersDb.findByEmail({ email: user.getEmail() }) if (exists) { throw UniqueConstraintError('Email') } const newUser = await usersDb.insert({ name: user.getName(), email: user.getEmail(), password: user.getPassword(), username: user.getUsername(), }) return newUser } }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM