Moment: [TypeScript] "error TS2304: No se puede encontrar el nombre 'momento'" cuando se usa con "módulo": "ninguno"

Creado en 14 feb. 2017  ·  51Comentarios  ·  Fuente: moment/moment

Mecanografiado parece no poder resolver la función moment() global cuando se usa en un contexto que no es de módulo.

tsc versión: 2.1.6
versión del momento: 2.17.1

Repro (asumiendo que tsc está en su $PATH ):

$ mkdir repro && cd repro
$ npm i moment
$ echo 'const now = moment();' > test.ts
$ tsc --module none test.ts
test.ts(1,13): error TS2304: Cannot find name 'moment'.

Sin embargo, el uso de un tipo de módulo funciona como se esperaba:

$ echo 'import * as moment from "moment"; const now = moment();' > test2.ts
$ tsc --module commonjs test2.js

Desafortunadamente, mi proyecto no usa un paquete o un sistema de módulos, por lo que estoy atascado con "module": "none" por ahora.

¿Mi única alternativa es usar algo como typings install --save --global dt~moment ?

TypeScript Up-For-Grabs

Comentario más útil

+1 por favor arregle esto

Todos 51 comentarios

Estoy enfrentando el mismo problema. No importa qué tipo de módulo especifique en tsconfig.json. Recibo el mismo error que @rossipedia

Informé el mismo problema (https://github.com/moment/moment/issues/3663), pero desafortunadamente se cerró sin ninguna reacción.

Terminé copiando moment.d.ts en mi directorio /scripts/app e implementé la solución especificada en https://github.com/moment/moment/issues/3663#issuecomment -273199291

Con suerte, una solución más permanente se abrirá camino en moment.d.ts eventualmente.

Resolví esto especificando "moduleResolution": "node" en mi tsconfig. No estoy seguro si esta es una opción para ustedes, pero parece funcionar.

"moduleResolution": "node" no me lo arregló, desafortunadamente

@rossipedia Yo tampoco.

¿No ayudaría agregar export as namespace moment; en el archivo moment.d.ts ?

Ver: https://github.com/moment/moment/issues/3808

@czb que tampoco me solucionó el problema, desafortunadamente :(

Resolví esto usando un par de trucos que otros han mencionado sobre un montón de problemas en muchos proyectos que tienen este problema. Simplemente envuélvalo en un archivo de definición personalizado propio. Esto está usando TypeScript 2.2. De esta manera, no estoy jugando con la dependencia que viene de npmjs.org y no tengo que verificar todo en el control de código fuente.

tsconfig.json

"compilerOptions": {
    "target": "ES5",
    "moduleResolution": "node",
    ...
}

moment.custom.d.ts

import * as _moment from 'moment';
export as namespace moment;
export = _moment;

Tengo curiosidad por saber por qué eso no funciona cuando ese código se agrega directamente a moment.d.ts . No puedo evitar pensar que nos estamos metiendo en algún oscuro error de resolución de TypeScript, y desafortunadamente tsc no tiene un modo detallado (que yo sepa) que ayude a identificar dónde van las cosas mal.

Creo que si se define "module": "none" mecanografiado no busca d.ts archivos bajo el node_modules/moment carpeta. Mi experiencia es que solo busca debajo de la carpeta node_modules/@types . Así que básicamente existen estas opciones.

  1. Copiar moment.d.ts debajo de node_modules/@types/moment
  2. Incluya /// <reference path="./node_modules/moment/moment.d.ts" /> en su archivo .ts
  3. Llamar tsc --typeRoots node_modules test.ts
  4. Coloque ./node_modules/moment/moment.d.ts en files sección de tsconfig.json

También necesita agregar export as namespace moment; en el archivo moment.d.ts .

al equipo de Moment le encantaría cualquier RP que solucionara este problema, pero sigue siendo compatible con TS 1.x.

Todavía tengo que encontrar una solución que funcione, pero cuando lo haga, me aseguraré de agregar un PR

De acuerdo con # 3663, la solución temporal para que funcione sin ningún paquete ...

  • Copiar moment.d.ts de node_modules/moment/ a node_modules/@types/moment

  • Cambie export = moment; en moment.d.ts por

declare module "moment" {
    export = moment;
}
  • Cambiar el nombre de moment.d.ts a index.d.ts

Solo use moment y su editor (en mi caso vscode) y tsc no debería quejarse

+1 por favor arregle esto

@mtgibbs ¿Dónde está poniendo el archivo moment.custom.d.ts? ¿Hay alguna otra configuración que deba realizarse para que su aplicación encuentre este archivo custom.d.ts?

@elSteeze

Sí, los estoy agregando a mi tsconfig.json . Aquí hay un ejemplo depurado:

{
  "compilerOptions": {
    "target": "ES5",
    "moduleResolution": "node",
    "typeRoots": [
      "./node_modules/@types"
    ]
  },
  "compileOnSave": true,
  "exclude": [
    "node_modules",
    "./path/to/typings/**/*.d.ts",
    "./typings"
  ],
  "include": [
    "./path/to/typings/moment.custom.d.ts",
    "./path/to/src/**/*.ts"
  ]
}

@mtgibbs ¡Hola, gracias tío! Aprecia la pronta respuesta. Lo intentaré.

@mtgibbs Lo siento por otra pregunta de novato, después de implementar su solución comencé a recibir errores de editor en la palabra clave de momento en mi código ts ...

'moment' refers to a UMD global, but the current file is a module. Consider adding an import instead

Hice una investigación personal e intenté implementar una solución reescribiendo moment.custom.d.ts, pero desafortunadamente, eso no solucionó mi problema.

Lo siento, no estoy tratando de ser uno de esos desarrolladores molestos que hace que todos los demás depuren su código, soy un graduado reciente y soy nuevo en el trabajo con bibliotecas de terceros en un entorno Angular 2

Aquí está mi module.custom.d.ts actualizado

declare var moment: any;
declare var module: NodeModule;
interface NodeModule {
    id: string;
}
import * as _moment from 'moment';
export as namespace moment;
export = _moment;

No hay problema. Si está usando Angular 2, debería estar en 2.0+ TS. No trabajo en Angular, así que no estoy seguro. Piense en pegar lo que pueda de su tsconfig.json y lo echaré un vistazo después de volver a una computadora real.

¡Seguro!

Este es mi archivo tsconfig.es5.json completo dentro del directorio src de mi módulo angular 2 que estoy construyendo.
Agradezco la ayuda por cierto

{
  "compilerOptions": {
    "declaration": true,
    "module": "es2015",
    "target": "es5",
    "baseUrl": ".",
    "stripInternal": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "outDir": "../build",
    "rootDir": ".",
    "lib": [
      "es2015",
      "dom"
    ],
    "skipLibCheck": true,
    "typeRoots": [
      "./node_modules/@types"
    ]
  },
  "compileOnSave": true,
  "exclude": [
    "node_modules",
    "./typings/**/*.d.ts",
    "./typings"
  ],
  "include": [
    "./typings/moment.custom.d.ts",
    "./src/**/*.ts"
  ],
  "angularCompilerOptions": {
    "annotateForClosureCompiler": true,
    "strictMetadataEmit": true,
    "skipTemplateCodegen": true,
    "flatModuleOutFile": "new-version-library.js",
    "flatModuleId": "new-version-library"
  },
  "files": [
    "./index.ts"
  ]
}

¿En qué versión de TS estás compilando? Deberías poder importar el momento en la parte superior sin mi truco.

@mtgibbs Estoy usando v2.2, y eso es lo que pensé. Desafortunadamente, no funciona. Estoy casi en el punto en el que escribo mi propia versión de la funcionalidad que estamos tomando de momentjs, porque parece que no puedo hacer que esto funcione.

@elSteeze

Ok, volviendo aquí. Noté que dijiste que hiciste un module.custom.d.ts , pero luego te refieres a mi moment.custom.d.ts en tu tsconfig.json . Asegúrese de haber creado moment.custom.d.ts y haberlo agregado a su compilador, nada de esas cosas adicionales que tenía declarando cosas. Luego, asegúrese de hacer referencia a él en la parte superior del archivo en el que desea usarlo.

/// <reference path="path/to/your/moment.custom.d.ts" />

Esto debería permitirle hacer referencia a ella como una variable global como en mi solución original.

¡Increíble gracias @mtgibbs ! Realmente aprecio la ayuda.
Modifiqué la estructura de mi archivo para admitir sus rutas. Entonces esos son los caminos correctos.
¡Salud!

Esto funciona para mi:

  • comentar // export = moment en el archivo oficial moment.d.ts
  • agregar node_modules/moment/moment.d.ts a tsconfig.json

Alternativamente, copie el moment.d.ts modificado en una ubicación de su elección y agregue la ruta en su tsconfig.json

Creo que el problema principal es que cuando se usa explícitamente "module":"none" en tsconfig.json, no puede tener ninguna importación o exportación de nivel superior en ninguna biblioteca (porque luego está usando módulos).

primero tienes que importar el componente como
importar * como momento de "momento";

funciono bien para mi

primero tienes que importar el componente como
importar * como momento de "momento";
funciono bien para mi

Si lo hace en un archivo, la resolución del espacio de nombres está deshabilitada para esos archivos.

Por favor chicos +1 para arreglar esto

¿Por qué no solucionas este problema? Es muy importante.

Agregar "module": "commonjs" al tsconfig.json me lo arregló

Pero tengo que usar "module": "none" . Commonjs no es una solución.

Si lo entiendo correctamente, esto se resolverá con la función de import ing sin afectar el contexto del módulo / ambiente.

Estoy usando TS 3.0.1, ¿esto ahora está resuelto? Al menos no funciona fuera de la caja.

EDITAR , con TS 3.0.1 podría hacer solo esto:

declare var moment: typeof import("moment");

¡Viva!

Con tsconfig

{
    "compilerOptions": {
        "module": "none"
        "moduleResolution": "node", 
        // ...
    }
}

TS 3.0.1 parece solucionar este problema (y ha estado abierto durante más de un año y medio sin tracción)

Hola rossipedia,
Estoy enfrentando el mismo problema en el proyecto angular-6. Según sus comentarios, se resolvió en TS 3.0.1 pero la CLI de angular6 no es compatible con la versión 3.0.1 de TypeScript.

¿Puede ayudarme a resolver este problema?

¿Alguien más también encontró el paquete @types/moment npm que es solo un código auxiliar y le dice que use el archivo que proporciona el paquete de momento normal?

... ¿Por qué el momento tiene que hacerlo de manera diferente en comparación con cualquier otro paquete? Esta es la razón por la que existe este problema, y ​​los desarrolladores pasaron miles de horas luchando con esto.

Claro, la solución de @Ciantic funciona en TS 3.0.1, pero no tengo que usar algo como declare var moment: typeof import("moment"); para ninguno de los otros paquetes que estoy usando.

No parece que Typecript 3.0.1 solucione ese problema, parece que solo nos da una solución.

parece que solo nos da una solución.

Sí, es exactamente esto. Esta no es una "solución" aceptable.

Solo ha pasado un día y me acabo de dar cuenta de que la solución alternativa de TS 3.0.1 solo importa la función moment , no el espacio de nombres / tipos. Entonces, si desea pasar un objeto de momento a una función, esto sucede:

image

Vuelva a abrir este problema, o mejor: corrija el archivo .dts.

No es una solución al problema original, pero para las personas que buscan en Google esto más adelante: especificar lo siguiente en tsconfig.json lo solucionó (mecanografiado 3.3.3 y momento 2.24.0)

{
  "compilerOptions": {
    "module": "commonjs"
  }
}

Ya no uso mucho el momento en estos días, pero estoy feliz de volver a abrir el problema si aún es válido.

ERROR en src / app / services / get-list.service.ts (22,54): error TS2304: No se puede encontrar el nombre '_'.

cual es la solucion para esto ??

@nagipogu No hay solución para eso, este problema es para moment.js , abra su problema en el repositorio de Github de underscore.js .

Me encuentro con este problema con la última versión del momento con la última versión de TS. ¿Alguien tiene alguna solución alternativa exitosa?

Todavía no funciona, la solución para mí fue yarn add -W [email protected] .

Cuando instalé la última versión de momento y miré en node_modules / moment / package.json, vi esto: https://github.com/moment/moment/blob/develop/package.json#L29 - pero no había un directorio existente node_modules/moment/ts3.1-typings , por lo que no es sorprendente que TS no pueda encontrarlo. Creo que puede haber algún error con un script de instalación (o un paquete) o algo así. Sí, tenemos "module": "esnext" en tsconfig.json.

Para mí se rompió con 2.25.0:

Usé pnpm add [email protected] como solución temporal.

Para mí se rompió con 2.25.0:

Usé pnpm add [email protected] como solución temporal.

funciona bien, gracias

Para mí se rompió con 2.25.0:

Usé pnpm add [email protected] como solución temporal.

Lo mismo aquí lo agregué a: "dependencies" {"moment": "^ 2.24.0",
} ... parece funcionar gracias.

La degradación a 2.24.0 también funcionó para mí. Parece una regresión en 2.25.0.

¿2.25.3 soluciona sus problemas?

Hay tantos tipos diferentes de situaciones en las que se usa Moment.js, y mucho menos TS 1.x, TS 2.x, TS 3.x ...
Dudo en hacer cambios que rompan a cualquier grupo de estos usuarios.

Si cree que se puede mejorar la documentación, publique en https://github.com/moment/momentjs.com/

¿2.25.3 soluciona sus problemas?

Si.

Retrocedió a 2.24.0 cuando 2.25.1 falló para mí en Angular 9. Con 2.25.3 está de nuevo en marcha nuevamente.

Vale genial. Cerraré por ahora.

Vuelva a abrir (o abra una nueva edición) si aún tiene dudas.

¿Fue útil esta página
0 / 5 - 0 calificaciones