我有一个接口(如下),我要实现的是更改属性req
,将其自定义类型本身req: { session: { userId?: string } }
添加到其中,是否可以合并我的类型和库{ {1}}类型?
Request
答案 0 :(得分:3)
当两个接口共享相同的名称时,后续的属性声明必须具有相同的类型。这意味着使用declaration merging 添加其他属性很容易,但是覆盖它并不容易。
当是十字路口
如果您只想向Request
添加另一个属性,则可以使用声明合并。
declare global {
interface Request {
session: {
userId?: string
}
}
}
是工会的时候
为了覆盖第三方库提供的定义,您需要为其创建自己的版本并将其包含在项目中。有一个缺点-它们不会合并在一起。您需要重新创建(或复制粘贴)您关心的my-module
提供的每个类型定义。
my-module.d.ts
declare module 'my-module' {
interface MyContext {
req: Request | { session: { userId?: string } };
res: Response;
}
}
但是,您实际上需要覆盖第三方类型定义这一事实几乎总是表明以下两种情况之一:
答案 1 :(得分:1)
您可以使用extends
:
interface MyContext extends Request {
//what ever props you want to add
}
现在MyContext
拥有分配给Request
类型的所有属性,以及您定义的任何内容。
如果由于某种原因您只需要Request
类型的特定部分,或者您不想使用接口,我建议您检出utility-types
库,尤其是Assign
,Pick
和Omit
类型。
您可以说:
type MyType = { ...whatever props you need to add}
type MyRequest = Assign<Request, MyType>
现在MyRequest
拥有您要添加的道具。
您还可以从Request
中选择类型或从中删除类型。假设Request
有一个foo
道具要删除:
type MyRequest = Omit<Request, 'foo'>
或者也许您只想要一个假想的道具bar
:
type JustBarFromRequest = Pick<Request, 'bar'>
,您可以Assign
认为合适的那些新类型。
如果您只需要在现有接口上构建,那么绝对要坚持使用extends
。如果您需要更改和组成道具和类型,我强烈建议您阅读有关utility-types