简体   繁体   English

将您的类型与现有的Typescript合并

[英]Merge your types with existing, Typescript

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? 我有一个接口(如下),我要实现的是更改属性req ,将其添加到我的自定义类型中,本身是req: { session: { userId?: string } } ,是否可以合并我的类型和库Request类型?

interface MyContext {
  req: Request;
  res: Response;
}

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. 如果只想向Request添加另一个属性,则可以使用声明合并。

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提供的每个类型定义。

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: 但是,您实际上需要覆盖第三方类型定义的事实几乎总是表明以下两种情况之一:

  • you are not using the library the way it was intended to be used, or 您没有按照预期的方式使用库,或者
  • the type definitions are incorrect and should be fixed upstream. 类型定义不正确,应在上游固定。

You can use extends : 您可以使用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. 现在, MyContext具有分配给Request类型的所有属性,以及您定义的任何属性。

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. 如果由于某种原因您只需要Request类型的特定部分,或者不想使用接口,建议您检查一下utility-types库,特别是它提供的AssignPickOmit类型。

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. 现在MyRequest具有您要添加的道具。

You could also pick types from, or remove types from Request . 您还可以从Request选择类型,或从Request删除类型。 Suppose Request has a foo prop that you want to remove: 假设Request具有您要删除的foo属性:

type MyRequest = Omit<Request, 'foo'>

or maybe you only want an imaginary prop called bar : 或者也许您只想要一个假想的道具,叫做bar

type JustBarFromRequest = Pick<Request, 'bar'>

and you can Assign those new types as you see fit. 然后您可以根据需要Assign这些新类型。

If you just need to build on an existing interface then definitely stick with extends . 如果只需要在现有接口上构建,则一定要坚持使用extends If you need to alter and compose props and types then I highly recommend reading about utility-types 如果您需要更改和组成道具和类型,那么我强烈建议阅读有关utility-types

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

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