2017-06-21 4 views
4

J'essaie ici d'étendre un espace de nom à partir des types de package, @typings/fullcalendar.Étendre un espace de noms à partir des types de package

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

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

// TimeGrid and fullcalendar.views are used then 

originaux typages peuvent être vus here.

Et fullcalendar-custom.d.ts est

import * as FC from 'fullcalendar'; 

export as namespace FC; 

declare class TimeGrid { prepareHits() } 

declare let views: any; 

Il en résulte des erreurs de type, il est donc évident que l'espace de noms fullcalendar n'a pas été étendu correctement:

TS2305: Module « » .../node_modules/@ types/fullcalendar/index "'n'a aucun membre exporté' TimeGrid '.

TS2339: La propriété 'vues' n'existe pas sur le type 'typeof ".../node_modules/@ types/ fullcalendar/index"'.

Comment cela devrait-il être fait de la bonne façon?

Est-il possible d'éviter la directive reference ici, étant donné que le répertoire types est spécifié dans typeRoots?

L'application est fournie avec Webpack et awesome-typescript-loader, ce qui fait que le comportement peut différer des autres méthodes de compilation. À un moment donné, les types semblaient bien fonctionner dans les inspections d'EDI (WebStorm), mais il y avait quand même des erreurs de type lors de la compilation.

Répondre

2

Nous pouvons importer un espace de noms dans une non-déclaration .ts, et l'exporter à nouveau comme un type étendu:

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

(Cela diffère en quelque sorte de votre scénario, dans ce J'utilise @types/ paquets et webpack ts-loader, mais vous devriez être capable de faire quelque chose de similaire.)

+0

Merci, j'ai essayé d'éviter de réexporter si possible puisque je n'ai pas étendu le paquet lui-même à l'endroit où j'étend les typages, mais il fait le travail.Je me suis retrouvé avec 'déclarer classe Complimentary ... export par défaut origFC; '. Un espace de nom était correct pour TS mais a causé quelques problèmes de type pour IDE. – estus

2

Vous pouvez n étendre facilement le 'fullcalendar' ou tout autre espace de noms TypeScript.

Exemple: créer un fichier 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; 
    } 
    } 
} 

Remarque: vérifiez que ce fichier est ramassé par le compilateur dactylographiée.

Utilisez les types nouvellement définis à partir du module étendu.

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

Pour plus d'informations sur les modules et les espaces de noms, vous pouvez vérifier la documentation dactylographiée sur Modules et Namespaces et de les utiliser together.

À la votre!

+0

Mais comment 'customNamespace' est supposé être reconnu dans 'one way'? J'essaie de faire 'import {TimeGrid} à partir de 'fullcalendar'; class CustomGrid étend TimeGrid {...} ', et TimeGrid et ses méthodes ne sont pas reconnus à partir de l'interface (et je ne vois pas comment cela fonctionnera dans la« seconde manière »). – estus

+0

Dans l'exemple donné TimeGrid est défini comme une interface, la classe CustomGrid ne peut l'implémenter. Si TimeGrid est une classe qui peut être étendue dans la librairie fullcalendar, déclarez-la comme une classe dans le fichier fullcalendar-extension.d.ts. C'est facile de remplacer le mot-clé 'interface' par 'class'. –

+0

A propos des importations, en raison des capacités limitées de déstructuration des objets dans les modules ES6, "customNamespace" peut uniquement être utilisé comme indiqué dans la "deuxième manière". –