Como o moment.js pode ser importado com o typescript?


93

Estou tentando aprender o texto datilografado. Embora eu não ache que seja relevante, estou usando o VSCode para esta demonstração.

Eu tenho um package.jsonque contém estas peças:

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

Então eu tenho uma classe Typescript main.jscomo esta:

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

Minha gulpfile.jsaparência é esta:

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'));
});

Quando executo o gulp build, recebo a mensagem: "../main.ts(1,25): Cannot file module 'moment'."

Se eu usar import moment = require('moment');, o jspm funcionará e trará o módulo quando executar o aplicativo, mas continuo recebendo o erro de compilação. Eu também tentei:

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

Em vez de melhorar o problema, ele piorou. Agora recebo o erro acima na compilação, bem como o seguinte:"../typings/browser/ambient/moment/index.d.ts(9,21): Cannot find namespace 'moment'."

Se eu for para o arquivo fornecido por digitação e adicionar no final do arquivo:

declare module "moment" { export = moment; }

Posso fazer com que o segundo erro desapareça, mas ainda preciso da instrução require para conseguir o momento de trabalhar em meu main.tsarquivo e ainda estou recebendo o primeiro erro de compilação.

Preciso criar meu próprio .d.tsarquivo por enquanto ou falta apenas alguma configuração?


Adicionando esta atualização para qualquer um que se depara com isso agora: import moment, { Moment } from 'moment';permite que você faça const x = moment();econst x: Moment = moment();
ryuu9187

Nenhuma dessas soluções funcionou, mudei para cá - github.com/date-fns/date-fns
chrismarx

Respostas:


119

Atualizar

Aparentemente, momento agora fornece suas próprias definições de tipo (de acordo com sivabudh pelo menos a partir 2.14.1 para cima), assim você não precisa typingsou @typesem tudo.

import * as moment from 'moment' deve carregar as definições de tipo fornecidas com o pacote npm.

Dito isso, no entanto, como dito em moment / pull / 3319 # issuecomment-263752265, a equipe do momento parece ter alguns problemas para manter essas definições (eles ainda estão procurando por alguém que as mantém) .


Você precisa instalar momenttipificações sem a --ambientbandeira.

Em seguida, inclua-o usando import * as moment from 'moment'


Isso funcionou. Você pode explicar a diferença entre usar a --ambientbandeira e não usar ? Consegui que o numeraljs trabalhasse com a ambient flag. Além disso, sua página principal npmjs.com/package/typings dá o exemplo usando o sinalizador de ambiente. Não sei quando quero / preciso usar um em vez do outro. Obrigado!
peinearydevelopment

1
Para ser honesto, não posso. Normalmente você usa o --ambientsinalizador para todas as definições de Typescript de typings/, DefinitelyTypedmas a momentdefinição tem uma estrutura estranha e os arquivos não são baixados corretamente. Se você olhar o arquivo de definição moment.d.ts, ele contém apenas uma referência à versão do nó, que não é resolvida no download (pode valer a pena abrir um problema).
Assessores de

Aparentemente, já existe um relacionado a esse problema: github.com/DefinitelyTyped/DefinitelyTyped/issues/8388
peinearydevelopment

1
Comecei a trabalhar usando import * como momento de 'momento / momento' b / c foi instalado como uma subpasta na pasta de módulos de nó.
user441058

1
Estou em um webpack, e agora a versão 2.17.1, mas ainda não consigo fazê-lo funcionar. Eu tentei: import * as moment from 'moment'; e importar * como momento de 'momento / momento'; e não está funcionando!
Mohy Eldeen

58

Você precisa importar moment () a função e Moment a classe separadamente no TS.

Eu encontrei uma nota na documentação datilografada aqui .

/ * ~ Observe que os módulos ES6 não podem exportar funções chamáveis ​​diretamente
* ~ Este arquivo deve ser importado usando o estilo CommonJS:
* ~ import x = require ('someLibrary');

Portanto, o código para importar moment js para o texto digitado realmente se parece com este:

import { Moment } from 'moment'
....
let moment = require('moment');
...
interface SomeTime {
  aMoment: Moment,
}
...
fn() {
  ...
  someTime.aMoment = moment(...);
  ...
}

1
Boa resposta, pois mostra a diferença entre o tipo e a função. Obrigado!
Jelle

não consigo encontrar o nome 'require'
Container Codificado

4
Agora, isso pode ser usado como import * as moment from 'moment';e depois usado moment.Momentpara digitações.
meteoro

O que funcionou para mim foi: import moment = require ('moment');
Telmo Pimentel Mota

Na verdade, você também pode usar a moment.Momentinterface diretamente do namespacemoment
HalfWebDev 01 de

19

Não tenho certeza de quando isso mudou, mas com a última versão do typescript, você só precisa usar import moment from 'moment';e tudo o mais deve funcionar normalmente.

ATUALIZAR:

Parece que o momento recente corrigiu sua importação. Pelo menos 2.24.0você vai querer usarimport * as moment from 'moment';


5
import * as moment from 'moment'não funcionará com texto datilografado, mas import moment from 'moment'funciona.
Stuart McIntyre

Está funcionando, mas estou obtendo a hora GMT 0, mas preciso da hora local que não está funcionando. Também tento com moment (). Utc (). Format () mas está retornando o mesmo resultado.
kbhaskar de

@kbhaskar na última versão do momento em que corrigiu sua importação. Ver resposta atualizada
NSjonas

1
Acho que é basicamente isso. A única etapa adicional que tive de fazer foi adicionar esModuleInteropset to truena minha configuração, que obtive com esta resposta . Obrigado.
Mark Birbeck

14

via digitação

Moment.js agora oferece suporte a TypeScript na v2.14.1.

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


Diretamente

Pode não ser a melhor resposta, mas este é o caminho da força bruta e funciona para mim.

  1. Basta baixar o moment.jsarquivo real e incluí-lo em seu projeto.
  2. Por exemplo, meu projeto se parece com este:

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

  1. E aqui está um exemplo de código-fonte:

`` `

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. Use apenas nodepara correr main.js.

Sim, eu confirmo que esta é a resposta correta. Funcionou como um encanto.
Capy de

Quando tento fazer isso usando npm i @ types / moment, recebo um erro: Erro de TypeScript: src \ app.ts (1,1): erro TS7038: Uma importação de estilo de namespace não pode ser chamada ou construída e causará uma falha no tempo de execução. em tsc -v 2.7.2
GONeale

1

Acabei de notar que a resposta que votei e comentei é ambígua. Portanto, o que se segue é exatamente o que funcionou para mim. Atualmente estou no Moment 2.26.0and TS 3.8.3:

Em código:

import moment from 'moment';

Na configuração do TS:

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

Estou construindo para tanto commonjs e EMS para que esta configuração é importado para outros arquivos de configuração.

O insight vem desta resposta que se refere ao uso do Express. Achei que valia a pena adicionar aqui, porém, para ajudar qualquer pessoa que pesquisa em relação ao Moment.js, ao invés de algo mais geral.


então você pode usar moment()normalmente em vez demoment.default()
xinthose


0

Ainda quebrado? Tente desinstalar @types/moment.

Então, removi o @types/momentpacote do package.jsonarquivo e funcionou usando:

import * as moment from 'moment'

As versões mais recentes momentdo não requerem o @types/momentpacote porque os tipos já estão incluídos.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.