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 關於模組和命名空間以及如何一起使用它們的文件。
乾杯!
