0

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

  1. module name: geojson
  2. parse: signature is parse(objects: any, params: any, callback?: any): any;
  3. GeoJSON is an interface ?

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?

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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

5 Comments

How come this answer got voted down? Did you try this Paul?
Paul can you explain why you down-voted my answer. While I agree that @Ivan's is more complete I don't think it deserved a down-vote
@WayneRiesterer I down-voted it, because the module declaration line was incorrect (it was redacted since) and also because it doesn't actually work. Yes the import statement won't error, but beyond that - it won't work. Please correct me if I am wrong and I will undo my downvote immediately :)
@tadwork It was me downvoting it. See the above comment ^^
@tadwork the typedef file on dt is for the geojson schema (geojson.org) not the npm package. thanks for the help

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.