Extending the namespace from typed packages
I'm trying to expand the namespace of typed packages @typings/fullcalendar
.
/// <reference path="./types/fullcalendar" />
import * as fullcalendar from 'fullcalendar';
import { TimeGrid } from 'fullcalendar';
// TimeGrid and fullcalendar.views are used then
The types of originals can be seen here .
And fullcalendar-custom.d.ts
import * as FC from 'fullcalendar';
export as namespace FC;
declare class TimeGrid { prepareHits() }
declare let views: any;
This leads to type errors, so it is obvious that the namespace was fullcalendar
not expanded correctly:
TS2305: Module '"... / node_modules / @ types / fullcalendar / index"' has no exported TimeGrid member.
TS2339: properties 'views' do not exist on typeof ... / node_modules / @ types / fullcalendar / index ".
How to do it right?
Can a directive be specified reference
here given that the directory types
is listed in typeRoots
?
The app is bundled with Webpack and awesome-w870> -loader, so the behavior may differ from other compilation methods. In some cases, the types seemed to be ok on IDE (WebStorm) checks, but still got type errors on compilation.
source to share
We can import the namespace in non-declarations .ts
and export it again as an expanded type:
// 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);
(This is somehow different from your scenario in that I'm using packages @types/
and webpack ts-loader
, but you should be able to do something like this.)
source to share
You can easily extend "fullcalendar" or any other TypeScript namespace.
Example: create a fullcalendar-extension.d.ts file
/// <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;
}
}
}
Note. Make sure this file is selected by the TypeScript compiler.
Use new types from the extended module.
// 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;
For more information on modules and namespaces, you can check the TypeScript documentation on Modules and Namespaces and use them together .
Hooray!
source to share