2017-06-21 54 views
4

我在這裏試圖擴展包裝類型的命名空間,@typings/fullcalendar從包裝類型擴展命名空間

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

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

// TimeGrid and fullcalendar.views are used then 

可以看到原件類型here

而且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:類型'typeof「.../node_modules/@ types/ fullcalendar/index」'上不存在屬性'views'。

這應該怎麼做纔是正確的?

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

該應用程序與Webpack和awesome-typescript-loader捆綁在一起,因此其行爲可能與其他編譯方法不同。在某些時候IDE的檢測類型(WebStorm)類型似乎沒有問題,但編譯時仍然出現類型錯誤。

回答

2

我們可以在無申報.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,但你應該可以做類似的事情。)

+0

謝謝,我儘量避免再次出口,因爲我沒有在延長打字的地方延長包裹,但它完成了工作。我結束了'聲明類免費...出口默認 origFC; '。 TS的名稱空間可以正常使用,但會導致IDE出現一些類型問題。 – estus

2

You ca n可輕鬆擴展'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; 
    } 
    } 
} 

注:確保打字稿編譯器這個文件被拾取。

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

// 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; 

有關模塊和命名空間,你可以在ModulesNamespaces檢查打字稿文件的詳細信息,並使用它們together

乾杯!

+0

但是'customNamespace'應該如何在'單向'中被識別?我正在嘗試從'fullcalendar'導入{TimeGrid};類CustomGrid擴展了TimeGrid {...}',並且TimeGrid及其方法無法從界面中識別(並且我沒有看到它如何以「第二種方式」工作)。 – estus

+0

在給定的例子中,TimeGrid被定義爲一個接口,類CustomGrid只能實現它。如果TimeGrid是可以在fullcalendar庫中擴展的類,則將其聲明爲fullcalendar-extension.d.ts文件中的類。用'class'代替'interface'關鍵字很簡單。 –

+0

關於導入,由於ES6模塊中有限的對象解構功能,'customNamespace'只能按照'第二種方式'使用。 –

相關問題