簡體   English   中英

Typescript 接口合並使返回類型更具體

[英]Typescript interface merging to make return type more specific

我想使用自定義類型定義來使 Express API 中的返回類型更加具體。 我們使用app.setapp.get在我們的應用程序中保存全局對象。

app.get('foo')返回一個特定的類MyClass ,所以我想使用 TypeScript 來表達這個事實,以避免必須顯式轉換。

對於現有的定義app.get在包括index.d.ts如下所示:

get: ((name: string) => any) & IRouterMatcher<this>;

在我的自定義類型定義中,我添加了以下內容:

import { MyClass } from '../MyClass';

declare global {
  namespace Express {
    export interface Application {
      get (name: 'foo'): MyClass;
      // also tried this to conform to existing structure:
      // get: ((name: 'foo') => MyClass);
    }
  }
}

但是在這兩種情況下, app.get('foo')的返回類型仍然是any

在執行以下操作時,是否可以隱式擁有正確的類型……:

let myObject = app.get('foo');

......並避免不得不寫:

let myObject: MyClass = app.get('foo');

好吧,使用當前版本的express.js 類型定義,我發現您可以使用此代碼增強get功能。

custom.d.ts

import { MyClass } from './MyClass';

declare module 'express-serve-static-core' {
  export interface IRouterMatcher<T> {
    (name: 'foo'): MyClass;
  }
}

解釋:

不幸的是,這是一個有點駭人聽聞的解決方案,因為您對看似無關的接口使用聲明合並 您需要這樣做,因為您不能像這個答案一樣使用全局Express命名空間擴充:

declare namespace Express {  
  export interface Application {
    get(name: 'foo'): MyClass; //doesn't work :(
  }
}

因為如果你仔細觀察類型,你會發現Express.Application中的getset方法使用extends關鍵字覆蓋了。

export interface Application extends IRouter, Express.Application {
  ...
  set(setting: string, val: any): Application;
  get: ((name: string) => any) & IRouterMatcher<this>;
  ...
}

您也不能增加getset方法,因為如果更改屬性類型,聲明合並將不起作用。

declare module 'express-serve-static-core' {
  export interface Application {
    get: ((name: string) => any) &
      IRouterMatcher<this> &
      ((name: 'foo') => MyClass);
      //Error: 'Error: Subsequent variable declarations must have the same type. :(
  }
}

我認為更清潔的解決方案是更改絕對類型類型 它的工作方式類似於在前面提到的問題中如何完成Request對象的擴充( get簽名需要表示為可以與您的自定義定義類型合並的接口)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM