網站搜尋

typescript - 從套件型別定義擴展命名空間


我在這裡嘗試從套件 typings,@typings/fullcalendar 擴展一個命名空間。

/// <reference path="./types/fullcalendar" />

import * as fullcalendar from 'fullcalendar';
import { TimeGrid } from 'fullcalendar';

// TimeGrid and fullcalendar.views are used then

原始打字可以在這裡看到。

而 fullcalendar-custom.d.ts 是

import * as FC from 'fullcalendar';

export as namespace FC;

declare class TimeGrid { prepareHits() }

declare let views: any;

這會導致類型錯誤,因此很明顯 fullcalendar 命名空間沒有被正確擴展:

TS2305:模組 '".../node_modules/@types/fullcalendar/index"' 沒有匯出的成員 'TimeGrid'。

TS2339:屬性 'views' 不存在於類型 'typeof ".../node_modules/@types/fullcalendar/index"' 上。

這應該怎麼正確地做?

考慮到 types 目錄已在 typeRoots 中指定,這裡可以避免使用 reference 指令嗎?

這個應用程式是使用 Webpack 和 awesome-typescript-loader 打包的,因此行為可能與其他編譯方法不同。在某些時候,型別在 IDE 檢查(WebStorm)中似乎是正確的,但在編譯時仍然出現型別錯誤。

答案#1

我們可以在非宣告的 .ts 檔案中匯入一個命名空間,然後再次將其作為擴展類型匯出:

// custom-fc.ts : enhances declaration of FC namespace
import * as origFC from "fullcalendar";

declare namespace Complimentary {
    class TimeGrid {
        prepareHits(): void;
    }
    let views: any;
}

// apply additional types to origFc and export again
export const FC: (typeof Complimentary & typeof origFC) = origFC as any;
// use-fc.ts : consumer of extended declaration
import { FC } from "./custom-fc";

console.log(FC.TimeGrid);
console.log(FC.views);

(這在某種程度上與你的情況不同,因為我使用的是 @types/ 套件和 webpack 的 ts-loader,但你應該也能做類似的事情。)

答案#2

您可以輕鬆擴展 'fullcalendar' 或任何其他 TypeScript 命名空間。

範例:建立 fullcalendar-extension.d.ts 檔案

/// <reference path="<path-to-typings-dir>/fullcalendar/index.d.ts" />

declare module 'fullcalendar' {

  export interface TimeGrid {

    customField: string;

    customMethod(arg1: number, arg2: boolean): boolean;

    prepareHits();
  }

  namespace customNamespace {

    export interface AnotherTimeGrid {
      customField1: string;
      customField2: boolean;
    }
  }
}

注意:確保此檔案被 TypeScript 編譯器識別。

使用擴展模組中新定義的類型。

// one way
import { TimeGrid } from 'fullcalendar';

const timeGrid: TimeGrid;

// second way
import * as fc from 'fullcalendar';

const timeGrid: fc.TimeGrid;
const anotherTimeGrid: fc.customNamespace.AnotherTimeGrid;

欲了解更多有關模組和命名空間的資訊,您可以查閱 TypeScript 關於模組和命名空間以及如何一起使用它們的文件。

乾杯!