Reputation: 2784
I have a interface (below), what I want to achieve is change property req
, add to it my custom type, per se req: { session: { userId?: string } }
, is it possible to merge my type and library Request
type?
interface MyContext {
req: Request;
res: Response;
}
Upvotes: 2
Views: 1140
Reputation: 25850
When two interfaces share the same name, subsequent property declarations must have the same type. This means it's easy to add another property using declaration merging, but it's not easy to override it.
When it's an intersection
If you want to simply add another property to Request
, you can use declaration merging.
declare global {
interface Request {
session: {
userId?: string
}
}
}
When it's a union
In order to override the definitions provided by a third-party library, you need to create your own version for them and include it in your project. There is a downside — they will not be merged together. You need to re-create (or copy-paste) every type definition delivered by my-module
you care about.
my-module.d.ts
declare module 'my-module' {
interface MyContext {
req: Request | { session: { userId?: string } };
res: Response;
}
}
However, the fact you need to override third-party type definitions almost always indicates one of two things:
Upvotes: 4
Reputation: 5780
You can use extends
:
interface MyContext extends Request {
//what ever props you want to add
}
Now MyContext
has all the properties assigned to the Request
type, as well as whatever you define.
If for some reason you only need specific parts of the Request
type or you do not want to use interfaces, I'd suggest checking out the utility-types
library, specifically the Assign
, Pick
, and Omit
types it provides.
You could say:
type MyType = { ...whatever props you need to add}
type MyRequest = Assign<Request, MyType>
and now MyRequest
has the props you'd like to add.
You could also pick types from, or remove types from Request
. Suppose Request
has a foo
prop that you want to remove:
type MyRequest = Omit<Request, 'foo'>
or maybe you only want an imaginary prop called bar
:
type JustBarFromRequest = Pick<Request, 'bar'>
and you can Assign
those new types as you see fit.
If you just need to build on an existing interface then definitely stick with extends
. If you need to alter and compose props and types then I highly recommend reading about utility-types
Upvotes: 1