¿Cómo se puede importar moment.js con mecanografiado?

96

Estoy tratando de aprender Typecript. Si bien no creo que sea relevante, estoy usando VSCode para esta demostración.

Tengo un package.jsonque tiene estas piezas:

{
  "devDependencies": {
    "gulp": "^3.9.1",
    "jspm": "^0.16.33",
    "typescript": "^1.8.10"
  },
  "jspm": {
    "moment": "npm:moment@^2.12.0"
  }
}

Entonces tengo una clase de TypeScript main.jscomo esta:

import moment from 'moment';
export class Main {
}

Mi gulpfile.jsaspecto es así:

var gulp = require('gulp');
var typescript = require('gulp-tsb');
var compilerOptions = {
                        "rootDir": "src/",
                        "sourceMap": true,
                        "target": "es5",
                        "module": "amd",
                        "declaration": false,
                        "noImplicitAny": false,
                        "noResolve": true,
                        "removeComments": true,
                        "noLib": false,
                        "emitDecoratorMetadata": true,
                        "experimentalDecorators": true
                      };
var typescriptCompiler = typescript.create(compilerOptions);
gulp.task('build', function() {
  return gulp.src('/src')
    .pipe(typescriptCompiler())
    .pipe(gulp.dest('/dest'));
});

Cuando ejecuto gulp build, aparece el mensaje: "../main.ts(1,25): Cannot file module 'moment'."

Si uso import moment = require('moment');, jspm funcionará y traerá el módulo cuando ejecuto la aplicación, pero sigo recibiendo el error de compilación. También probé:

npm install typings -g
typings install moment --ambient --save

Sin embargo, en lugar de mejorar el problema, empeoró. Ahora obtengo el error anterior en la compilación, así como lo siguiente:"../typings/browser/ambient/moment/index.d.ts(9,21): Cannot find namespace 'moment'."

Si voy al archivo provisto por mecanografía y agrego en la parte inferior del archivo:

declare module "moment" { export = moment; }

Puedo hacer que el segundo error desaparezca, pero todavía necesito la declaración require para que el momento funcione en mi main.ts archivo y sigo recibiendo el primer error de compilación.

¿Necesito crear mi propio .d.tsarchivo por un momento o solo me falta alguna pieza de configuración?

desarrollo peineario
fuente
1
Agregar esta actualización para cualquiera que se encuentre con esto ahora: le import moment, { Moment } from 'moment';permite hacerlo const x = moment();yconst x: Moment = moment();
ryuu9187
Ninguna de estas soluciones funcionó, me mudé aquí - github.com/date-fns/date-fns
chrismarx

Respuestas:

124

Actualizar

Aparentemente, moment ahora proporciona sus propias definiciones de tipo (de acuerdo con sivabudh al menos desde 2.14.1 en adelante ), por lo que no necesita typingso@types en absoluto.

import * as moment from 'moment' debe cargar las definiciones de tipo proporcionadas con el paquete npm.

Dicho esto, sin embargo, como se dijo en moment / pull / 3319 # issuecomment-263752265, el equipo de momento parece tener algunos problemas para mantener esas definiciones (todavía están buscando a alguien que las mantenga) .


Necesita instalar momentmecanografía sin la --ambientbandera.

Luego inclúyelo usando import * as moment from 'moment'

Ayudantes
fuente
Eso funciono. ¿Puedes explicar la diferencia entre usar la --ambientbandera y no? Conseguí que numeraljs funcionara usando la bandera ambiental. Además, su página principal npmjs.com/package/typings da el ejemplo usando la bandera ambiental. No sé cuándo querría / necesitaría usar uno sobre el otro. ¡Gracias!
peineario
1
Para ser honesto, no puedo. Normalmente, usa la --ambientbandera para todas las definiciones de TypeScript de typings/ DefinitelyTypedpero la momentdefinición tiene una estructura extraña y los archivos no se descargan correctamente. Si observa el archivo de definición moment.d.ts , solo contiene una referencia a la versión del nodo, que no se resuelve en la descarga (podría valer la pena abrir un problema).
Aides
Aparentemente ya hay uno relacionado con este problema: github.com/DefinitelyTyped/DefinitelyTyped/issues/8388
peinearydevelopment
1
Lo hice funcionar usando la importación * como momento de 'momento / momento' porque se instaló como una subcarpeta en la carpeta node-modules.
user441058
1
Estoy en un paquete web, y el momento de la versión 2.17.1 pero todavía no puedo hacer que funcione. Intenté: importar * como momento de 'momento'; e importar * como momento de 'momento / momento'; y no funciona!
Mohy Eldeen
59

Necesita importar moment () la función y Moment la clase por separado en TS.

Encontré una nota en los documentos mecanografiados aquí .

/ * ~ Tenga en cuenta que los módulos ES6 no pueden exportar directamente funciones invocables
* ~ Este archivo debe importarse usando el estilo CommonJS:
* ~ import x = require ('someLibrary');

Entonces, el código para importar el momento js en mecanografiado en realidad se ve así:

import { Moment } from 'moment'
....
let moment = require('moment');
...
interface SomeTime {
  aMoment: Moment,
}
...
fn() {
  ...
  someTime.aMoment = moment(...);
  ...
}
Koby
fuente
1
Buena respuesta ya que muestra la diferencia entre el tipo y la función. ¡Gracias!
Jelle den Burger
no se puede encontrar el nombre 'require'
Contenedor codificado
4
Ahora, esto se puede usar como import * as moment from 'moment';y luego usar moment.Momentpara mecanografiar.
meteoro
Lo que funcionó para mí fue: import moment = require ('moment');
Telmo Pimentel Mota
En realidad, también puede usar la moment.Momentinterfaz directamente desde el espacio de nombresmoment
HalfWebDev
20

No estoy seguro de cuándo cambió esto, pero con la última versión de mecanografiado, solo necesita usar import moment from 'moment';y todo lo demás debería funcionar normalmente.

ACTUALIZAR:

Parece que el momento reciente corrigió su importación. Al menos 2.24.0querrás usarimport * as moment from 'moment';

NSjonas
fuente
5
import * as moment from 'moment'no funcionará con mecanografiado, pero import moment from 'moment'sí.
Stuart McIntyre
Está funcionando pero estoy obteniendo la hora de GMT 0, pero necesito la hora local que no funciona. También lo intento con moment (). Utc (). Format () pero está obteniendo el mismo resultado.
kbhaskar
@kbhaskar a partir de la última versión del momento en que arreglaron su importación. Ver respuesta actualizada
NSjonas
1
Creo que esto es todo. El único paso adicional que tuve que hacer fue agregar un esModuleInteropconjunto trueen mi configuración, que obtuve de esta respuesta . Gracias.
Mark Birbeck
14

a través de mecanografía

Moment.js ahora es compatible con TypeScript en v2.14.1.

Ver: https://github.com/moment/moment/pull/3280


Directamente

Puede que no sea la mejor respuesta, pero esta es la forma de la fuerza bruta, y funciona para mí.

  1. Simplemente descargue el moment.js archivo e inclúyalo en su proyecto.
  2. Por ejemplo, mi proyecto se ve así:

$ tree . ├── main.js ├── main.js.map ├── main.ts └── moment.js

  1. Y aquí hay un código fuente de muestra:

''

import * as moment from 'moment';

class HelloWorld {
    public hello(input:string):string {
        if (input === '') {
            return "Hello, World!";
        }
        else {
            return "Hello, " + input + "!";
        }
    }
}

let h = new HelloWorld();
console.log(moment().format('YYYY-MM-DD HH:mm:ss'));
  1. Solo usa nodepara correr main.js.
sivabudh
fuente
Sí, confirmo que esta es la respuesta correcta. Trabajado como un encanto.
Capy
Cuando intento hacer esto usando npm i @ types / moment, recibo un error: Error de TypeScript: src \ app.ts (1,1): error TS7038: No se puede llamar ni construir una importación de estilo de espacio de nombres, y causará una falla en tiempo de ejecución. en tsc -v 2.7.2
GONeale
2

Acabo de notar que la respuesta que voté y comenté es ambigua. Así que lo siguiente es exactamente lo que funcionó para mí. Actualmente estoy en Moment 2.26.0y TS3.8.3 :

En codigo:

import moment from 'moment';

En la configuración de TS:

{
  "compilerOptions": {
    "esModuleInterop": true,
    ...
  }
}

Estoy construyendo para ambos CommonJS y EMS por lo que esta configuración se importa en otros archivos de configuración.

La idea proviene de esta respuesta que se relaciona con el uso de Express. Sin embargo, pensé que valía la pena agregarlo aquí para ayudar a cualquiera que busque en relación con Moment.js, en lugar de algo más general.

Mark Birbeck
fuente
entonces puedes usarlo moment()como de costumbre en lugar demoment.default()
xinthose
0

1. momento de instalación

npm install moment --save

2. pruebe este código en su archivo mecanografiado

import moment = require('moment');

console.log(moment().format('LLLL'));
lutula resistente
fuente
1
Esta no es la forma correcta de importar un módulo en mecanografiado. Considere actualizar su respuesta. Consulte esto para confirmación: basarat.gitbook.io/typescript/project/modules/external-modules
Efe Ariaroo
0

¿Aún roto? Intente desinstalar @types/moment.

Entonces, eliminé el @types/momentpaquete del package.jsonarchivo y funcionó usando:

import * as moment from 'moment'

Las versiones más recientes de momentno requieren el @types/momentpaquete, ya que los tipos ya están incluidos.

Ben Winding
fuente