Reputation: 45
I'm having issues creating a typescript definition file a 'simple' npm module.
Here are the details:
Issue: when I compile the typescript it get the following error:
play.ts(1,9): error TS2305: Module '"/to/the/dir/node_modules/geojson/geojson"' has no exported member 'GeoJSON'.
Module: geojson (https://www.npmjs.com/package/geojson). The package only has one public function. it is in a file geojson.js:
(function(GeoJSON) {
GeoJSON.version = '0.3.0';
GeoJSON.defaults = {};
// The one and only public function.
// Converts an array of objects into a GeoJSON feature collection
GeoJSON.parse = function(objects, params, callback) {
...
...
...
(typeof module == 'object' ? module.exports : window.GeoJSON = {}));
The package.json includes
"main": "./geojson",
"name": "geojson",
//// I ADDED THIS TYPE DEF FILE
"typings": "./geojson.d.ts",
From this i gather
My definition file is: geojson.d.ts
export declare module geojson {
interface GeoJSON {
parse(objects: any, params: any, callback?: any): any;
}
}
My tsconfig file is:
{
"compilerOptions": {
"target": "es5",
"module": "system",
"moduleResolution": "node",
"sourceMap": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"removeComments": false,
"noImplicitAny": false
}
}
I'm trying to import (I've tried 1000 ways..) here are some:
import GeoJSON from 'geojson';
import geojson from 'geojson';
import {geojson} from geojson;
import geojson = require('geojson');
import GeoJSON = require('geojson');
What am I doing wrong?
Upvotes: 0
Views: 730
Reputation: 174
looks like the module definition you wrote are not getting exported (made available publicly).
declare module 'geojson' {
export interface GeoJSON {
parse(objects: any, params: any, callback?: any): any;
}
}
you should then be able to consume it using:
import {GeoJSON} from 'geojson';
have you considered using the typings already available for this library at DefinitelyTyped? EDIT: as Paul mentioned in the comments the only available typings seem to be for the GeoJson schema not the library
Upvotes: 0
Reputation: 13196
Assuming there are no publicly available typings already - the correct type declaration in your case should be as per below.
You shouldn't be editing the package.json
and instead should either consume typings using the typings
tool or alternatively save the below type definition somewhere in your source folder as something-or-other.d.ts
. I would also recommend adding exclude: [ "node_modules" ]
to your tsconfig.json
to prevent it from processing anything in the node_modules
folder (currently it will recursively process everything).
The module doesn't have any namespace or interface per se. Keep in mind that in the file itself is a "namespace" (this is confusing at first if you are coming from .NET/Java, etc.)
declare module 'geojson' {
export var version : string;
export var defaults: Object;
export function parse(data: Object, propreties: Object, callback?: Function) : Object;
}
Consume like this:
import * as geoJson from 'geojson';
var data = [
{ name: 'Location A', category: 'Store', lat: 39.984, lng: -75.343, street: 'Market' },
{ name: 'Location B', category: 'House', lat: 39.284, lng: -75.833, street: 'Broad' },
{ name: 'Location C', category: 'Office', lat: 39.123, lng: -74.534, street: 'South' }
];
var result = geoJson.parse(data, {Point: ['lat', 'lng']});
console.log(result);
Generates this JavaScript:
"use strict";
var geoJson = require('geojson');
var data = [
{ name: 'Location A', category: 'Store', lat: 39.984, lng: -75.343, street: 'Market' },
{ name: 'Location B', category: 'House', lat: 39.284, lng: -75.833, street: 'Broad' },
{ name: 'Location C', category: 'Office', lat: 39.123, lng: -74.534, street: 'South' }
];
var result = geoJson.parse(data, { Point: ['lat', 'lng'] });
console.log(result);
Output:
c:\code\tmp\geojson>node build\main.js
{ type: 'FeatureCollection',
features:
[ { type: 'Feature', geometry: [Object], properties: [Object] },
{ type: 'Feature', geometry: [Object], properties: [Object] },
{ type: 'Feature', geometry: [Object], properties: [Object] } ] }
Have a look at a blog I wrote with more info about typings discovery, etc:
http://ivanz.com/2016/06/07/how-does-typescript-discover-type-declarations-definitions-javascript/
This is a sort of "ambient" type declaration that will work as the file it's in is included in the file. It tells TypeScript "Hey, TypeScript - there exists a module called geojson which has the following members". In your case the module will be a NPM one living in node_modules
.
There are other ways to write typings if you were for example doing it for a local javascript file (not an npm package) or as an NPM package author, which boils down to writing an "external" module type declaration which has a file name (module.d.ts
if you have module.js
and is in the same directory as the module.js
). In such cases the declaration will not include a "declare module" bit, because it's bound to the .js file directly.
Upvotes: 1