Definitelytyped: proj4-Types not working with proj4 2.4.3

Created on 5 Apr 2017  路  29Comments  路  Source: DefinitelyTyped/DefinitelyTyped

  • [X] I tried using the @types/proj4 package and had problems.
  • [X] I tried using the latest stable version of tsc. https://www.npmjs.com/package/typescript
  • [x] [Mention](https://github.com/blog/821-mention-somebody-they-re-notified) the authors (see Definitions by: in index.d.ts) so they can respond.

    • Authors: @DenisCarriere

I have tried using the latest version of proj4 (2.4.3) with the latest version of @types/proj4, but it doesn't work. I keep getting errors at runtime because proj4 seems to be undefined.

Dependencies:
"@types/proj4": "^2.3.4", "proj4": "2.4.3", "typescript": "2.2.2"

Usage of proj4:
import * as proj4 from 'proj4';
let proj4Defs = [
[
// CH1903
'EPSG:4149',
'+proj=longlat +ellps=bessel +towgs84=674.374,15.056,405.346,0,0,0,0 +no_defs'
], [
// ETRS89
'EPSG:4258',
'+proj=longlat +ellps=GRS80 +no_defs'
]
];
proj4.defs(proj4Defs);

Errormessage:

Error: Uncaught (in promise): TypeError: proj4.defs is not a function
TypeError: proj4.defs is not a function

Most helpful comment

My workaround:

import * as proj4x from 'proj4';
let proj4 = (proj4x as any).default;

All 29 comments

Can you try just import * as proj4 from "proj4"; console.log(proj4);?

Just tried the Typescript definition & proj4 and I didn't receive any errors (sounds like you have another library that uses an older version of proj4 that might be causing this issue).

Error: Uncaught (in promise): TypeError: proj4.defs is not a function

Doesn't look like you're using the same code to report this issue.

import * as proj4 from 'proj4'

proj4.defs('WGS84')

Output of proj4

> const proj4 = require('proj4')
> proj4
{ [Function: proj4$1]
  defaultDatum: 'WGS84',
  Proj: 
   { [Function: Projection$1]
     projections: 
      { start: [Function: start],
        add: [Function: add],
        get: [Function: get] } },
  WGS84: 
   Projection$1 {
     title: 'WGS 84 (long/lat)',
     projName: 'longlat',
     ellps: 'WGS84',
     datumCode: 'WGS84',
     units: 'degrees',
     datum_params: [ '0', '0', '0' ],
     datumName: 'WGS84',
     k0: 1,
     axis: 'enu',
     init: [Function: init$1],
     forward: [Function: identity],
     inverse: [Function: identity],
     names: [ 'longlat', 'identity' ],
     a: 6378137,
     b: 6356752.314245179,
     rf: 298.257223563,
     sphere: undefined,
     es: 0.006694379990141316,
     e: 0.08181919084262149,
     ep2: 0.006739496742276434,
     datum: 
      { datum_type: 4,
        datum_params: [Object],
        a: 6378137,
        b: 6356752.314245179,
        es: 0.006694379990141316,
        ep2: 0.006739496742276434 } },
  Point: { [Function: Point] fromMGRS: [Function] },
  toPoint: [Function: toPoint],
  defs: 
   { [Function: defs]
     'EPSG:4326': 
      { title: 'WGS 84 (long/lat)',
        projName: 'longlat',
        ellps: 'WGS84',
        datumCode: 'WGS84',
        units: 'degrees',
        datum_params: [Object],
        datumName: 'WGS84',
        k0: 1,
        axis: 'enu' },
     'EPSG:4269': 
      { title: 'NAD83 (long/lat)',
        projName: 'longlat',
        a: 6378137,
        b: 6356752.31414036,
        ellps: 'GRS80',
        datumCode: 'nad83',
        units: 'degrees' },
     'EPSG:3857': 
      { title: 'WGS 84 / Pseudo-Mercator',
        projName: 'merc',
        a: 6378137,
        b: 6378137,
        lat_ts: 0,
        long0: 0,
        x0: 0,
        y0: 0,
        k0: 1,
        units: 'm',
        datumCode: 'none',
        no_defs: true },
     WGS84: 
      { title: 'WGS 84 (long/lat)',
        projName: 'longlat',
        ellps: 'WGS84',
        datumCode: 'WGS84',
        units: 'degrees',
        datum_params: [Object],
        datumName: 'WGS84',
        k0: 1,
        axis: 'enu' },
     'EPSG:3785': 
      { title: 'WGS 84 / Pseudo-Mercator',
        projName: 'merc',
        a: 6378137,
        b: 6378137,
        lat_ts: 0,
        long0: 0,
        x0: 0,
        y0: 0,
        k0: 1,
        units: 'm',
        datumCode: 'none',
        no_defs: true },
     GOOGLE: 
      { title: 'WGS 84 / Pseudo-Mercator',
        projName: 'merc',
        a: 6378137,
        b: 6378137,
        lat_ts: 0,
        long0: 0,
        x0: 0,
        y0: 0,
        k0: 1,
        units: 'm',
        datumCode: 'none',
        no_defs: true },
     'EPSG:900913': 
      { title: 'WGS 84 / Pseudo-Mercator',
        projName: 'merc',
        a: 6378137,
        b: 6378137,
        lat_ts: 0,
        long0: 0,
        x0: 0,
        y0: 0,
        k0: 1,
        units: 'm',
        datumCode: 'none',
        no_defs: true },
     'EPSG:102113': 
      { title: 'WGS 84 / Pseudo-Mercator',
        projName: 'merc',
        a: 6378137,
        b: 6378137,
        lat_ts: 0,
        long0: 0,
        x0: 0,
        y0: 0,
        k0: 1,
        units: 'm',
        datumCode: 'none',
        no_defs: true } },
  transform: [Function: transform],
  mgrs: 
   { forward: [Function: forward$1],
     inverse: [Function: inverse$1],
     toPoint: [Function: toPoint$1] },
  version: '2.4.3' }

CC: @RicciR @andy-ms

I've just encountered the same. My defs function is located at proj4.default.defs.

console.log(proj4);

image

The folks at Proj4 just recently changed their index.js export to default two months ago.
https://github.com/proj4js/proj4js/pull/232/files

~We would need to change the DT types to support default import now.~

~Importing proj4 now would be:~

import proj4 from 'proj4'

@DenisCarriere Are they still supporting the old import style? Otherwise I would expect a major version change.

Thanks for the comment on Proj4's PR. This change was done on a minor release 2.3.18-alpha so I don't think changing the Typescript definition just yet would be recommended.

@DenisCarriere As of today, the following does not yield a working setup:

npm install proj4 @types/proj4

My workaround:

import * as proj4x from 'proj4';
let proj4 = (proj4x as any).default;

Agreed, however all other versions of Proj4 2.3.X does work with the current Typescript Definition.

~I don't think their change was intentional to cause a breaking change in their minor release.~

Ok I've tried this again and there seems to be no issues with the recent Proj4 current release.

@andy-ms I'd suggest closing this issue since it can't be replicated.

package.json

{
  "dependencies": {
    "@types/proj4": "^2.3.4",
    "proj4": "^2.4.3",
    "typescript": "^2.2.2"
  }
}

test.ts

import * as proj4 from 'proj4'
console.log(proj4.defs)

output

$ tsc test.ts --target ES5
$ node test.js
{ [Function: defs]
  'EPSG:4326': 
   { title: 'WGS 84 (long/lat)',
     projName: 'longlat',
     ellps: 'WGS84',
     datumCode: 'WGS84',
     units: 'degrees',
     datum_params: [ '0', '0', '0' ],
     datumName: 'WGS84',
     k0: 1,
     axis: 'enu' },
  'EPSG:4269': 
   { title: 'NAD83 (long/lat)',
     projName: 'longlat',
     a: 6378137,
     b: 6356752.31414036,
     ellps: 'GRS80',
     datumCode: 'nad83',
     units: 'degrees' },
  'EPSG:3857': 
   { title: 'WGS 84 / Pseudo-Mercator',
     projName: 'merc',
     a: 6378137,
     b: 6378137,
     lat_ts: 0,
     long0: 0,
     x0: 0,
     y0: 0,
     k0: 1,
     units: 'm',
     datumCode: 'none',
     no_defs: true },
  WGS84: 
   { title: 'WGS 84 (long/lat)',
     projName: 'longlat',
     ellps: 'WGS84',
     datumCode: 'WGS84',
     units: 'degrees',
     datum_params: [ '0', '0', '0' ],
     datumName: 'WGS84',
     k0: 1,
     axis: 'enu' },
  'EPSG:3785': 
   { title: 'WGS 84 / Pseudo-Mercator',
     projName: 'merc',
     a: 6378137,
     b: 6378137,
     lat_ts: 0,
     long0: 0,
     x0: 0,
     y0: 0,
     k0: 1,
     units: 'm',
     datumCode: 'none',
     no_defs: true },
  GOOGLE: 
   { title: 'WGS 84 / Pseudo-Mercator',
     projName: 'merc',
     a: 6378137,
     b: 6378137,
     lat_ts: 0,
     long0: 0,
     x0: 0,
     y0: 0,
     k0: 1,
     units: 'm',
     datumCode: 'none',
     no_defs: true },
  'EPSG:900913': 
   { title: 'WGS 84 / Pseudo-Mercator',
     projName: 'merc',
     a: 6378137,
     b: 6378137,
     lat_ts: 0,
     long0: 0,
     x0: 0,
     y0: 0,
     k0: 1,
     units: 'm',
     datumCode: 'none',
     no_defs: true },
  'EPSG:102113': 
   { title: 'WGS 84 / Pseudo-Mercator',
     projName: 'merc',
     a: 6378137,
     b: 6378137,
     lat_ts: 0,
     long0: 0,
     x0: 0,
     y0: 0,
     k0: 1,
     units: 'm',
     datumCode: 'none',
     no_defs: true } }

Hm, that works for me, but proj4's source code uses export default. Wonder why @RicciR and @alienlike are getting something with a default property and we're not.

@andy-ms I know... very strange behaviour, I can't wrap my head around it.

FWIW, I'm using Typescript 2.0 and Webpack.

My tsconfig.json:

{
  "compilerOptions": {
    "moduleResolution": "node",
    "target": "es5",
    "sourceMap": true,
    "noImplicitAny": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "skipDefaultLibCheck": true,
    "skipLibCheck": true,
    "lib": [ "es6", "dom" ],
    "types": [ "node" ]
  },
  "exclude": [ "bin", "node_modules" ],
  "atom": { "rewriteTsconfig": false }
}

I'm also using Webpack and the latest version of typescript.

I'm on the node-js LTS, so 6.10.0

I don't know what's the problem here, I've changed my definition to use export default proj4 and now I'm getting errors.

test.ts

import proj4 from 'proj4'

console.log(proj4.defs)

Error Output

console.log(proj4_1["default"].defs);
                              ^

TypeError: Cannot read property 'defs' of undefined
    at Object.<anonymous> (/Users/mac/Github/test/test.js:4:31)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.runMain (module.js:604:10)
    at run (bootstrap_node.js:393:7)
    at startup (bootstrap_node.js:150:9)
    at bootstrap_node.js:508:3

@DenisCarriere That's because when you require("proj4"), the result doesn't have a default property. But for @alienlike and @RicciR it does. Probably has something to do with WebPack intercepting it? @alienlike @RicciR, try using --allowSyntheticDefaultImports.

Sounds like it would be Webpack or some middleware that's changing the require behaviour.

Having the exact same issue has discribed by @alienlike and @RicciR on a mobile app project using NativeScript + Angular2.
Works fine using CommonJS, but when I bundle it with Webpack the "defs" function end up in proj4.default.defs

Feel free to send a PR to DT or directly to proj4 with a solution.

I'm currently using the workaround proposed by @alienlike
Don't know the proper solution yet, nor what exactly is causing this when using Webpack.
I'll sure share if I figure it out.

any progress !!!! on this issue

I am using TypeScript 2.5 in Visual Studio (2015). Downloaded the latest type definitions using npm @types/proj4. These did not work right out of the box in my environment. However, if I change the namespace declaration in proj4 (index.d.ts) to a module, it works like the other typescript definitions. After I changed the namespace to a module, I dont need any import statement in my .ts-files. I am new to TypeScript and probably doesnt understand modules/definitions properly. Can anyone help me shed some light over whats happening here?

The latest types for proj4 resolves to :

@types/[email protected]

It uses a default export:

export = proj4;

But for typescript I believe it should read:

export default proj4;

Changing this in the index.d.ts file has resolved the issue for me, now I can do:

import proj4 from 'proj4';

proj4.defs("ESRI:54029",.... etc)

Probably need to get this updating in the types package-

@chriszrc https://github.com/DefinitelyTyped/DefinitelyTyped#a-package-uses-export--but-i-prefer-to-use-default-imports-can-i-change-export--to-export-default

That was it! Thanks!

Edit
Just to be specific, for my angular app at least, I actually needed both properties:

"allowSyntheticDefaultImports": true,
"esModuleInterop":true

I get it working by following these steps

  1. Change in the index.d.ts file export = proj4; to export default proj4;
  2. Add to the typecript file containing map definition
import * as ol from "openlayers";
import proj4 from 'proj4';
ol.proj.setProj4(proj4);

Ref --> http://openlayers.org/en/latest/apidoc/ol.proj.html

Here are the packages versions

"openlayers": "^4.6.5", "proj4": "^2.4.4", "@types/openlayers": "^4.6.9", "@types/proj4": "^2.3.4",

The following appears to throw an error in typescript:

let oProj = new Proj4.Proj(someProjection)

any ideas why?

This issue is still valid and it just doesn't work as described here:
https://www.npmjs.com/package/proj4

I tried hundreds of options and I don't get it to work. My scenario is a common one I guess. I'm writing a npm package and inside the package I'm using proj4 and it's types both at 2.5.0.

Later I use my package inside an angular app.

Whatever I do, inside my angular app proj4 module object has the structure
proj4_export

which makes it impossible to execute predefined proj4 definitions like (http://epsg.io/4326.js).

So I need this proj4 default object somehow in my global scope.

My current workaround:

  1. In index.d.ts on proj4 set 'export default proj4' as recommended. Now if I do
    import * as proj4internal from 'proj4';
    in my npm package I get valid proj4internal.default just like in angular app.
  2. Now I need proj4internal.default to exist as proj4 in my angular app. I solved it like that:
    In my npm package I do: export const proj4 = proj4internal.default;
    In my angular app I do:
    import { proj4 } from 'myPackage';

declare global {
interface Window { proj4: any; }
}

window.proj4 = proj4;

Was this page helpful?
0 / 5 - 0 ratings