2017-06-21 84 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'只能按照'第二种方式'使用。 –

相关问题