代码之家  ›  专栏  ›  技术社区  ›  Ramazan Chasygov

将类型与现有的typescript合并

  •  1
  • Ramazan Chasygov  · 技术社区  · 6 年前

    我有一个接口(如下),我想要实现的是改变属性 req ,添加我的自定义类型 req: { session: { userId?: string } } ,是否可以合并我的类型和库 Request 类型?

    interface MyContext {
      req: Request;
      res: Response;
    }
    
    2 回复  |  直到 6 年前
        1
  •  3
  •   Karol Majewski    6 年前

    当两个接口共享相同的名称时,后面的属性声明必须具有相同的类型。这意味着很容易 添加 另一个属性使用 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;
      }
    }
    

    但是,需要重写第三方类型定义的事实几乎总是指示以下两种情况之一:

    • 您没有按照预期的方式使用库,或者
    • 类型定义不正确,应在上游固定。
        2
  •  1
  •   Robbie Milejczak Diego Felipe    6 年前

    你可以使用 extends :

    interface MyContext extends Request {
      //what ever props you want to add
    }
    

    现在 MyContext 已将所有属性分配给 Request 类型,以及您定义的任何内容。

    如果出于某种原因,您只需要 请求 键入或您不想使用接口,我建议签出 utility-types 图书馆,特别是 Assign , Pick Omit 它提供的类型。

    你可以说:

    type MyType = { ...whatever props you need to add}
    type MyRequest = Assign<Request, MyType>
    

    现在 MyRequest 有你想要添加的道具。

    您还可以从中选择类型,或从中删除类型 请求 . 假设 请求 有一个 foo 要删除的道具:

    type MyRequest = Omit<Request, 'foo'>
    

    或者你只想要一个虚构的道具 bar :

    type JustBarFromRequest = Pick<Request, 'bar'>
    

    你可以 赋值 你认为合适的新类型。

    如果您只需要在现有接口上构建,那么一定要坚持 延伸 . 如果您需要修改和撰写道具和类型,那么我强烈建议您阅读 utility-types