[英]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?我希望能够为
PostDb
和CommentDb
重用这个接口,而不必编写另一个描述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
,与Result
和UserResult
相同:
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.