Typescript: Suporte à procura de módulos em node_modules ao importar

Criado em 25 jul. 2014  ·  138Comentários  ·  Fonte: microsoft/TypeScript

Atualização 5 de novembro de 2015

A funcionalidade solicitada abaixo está atualmente implementada em texto datilografado desde pelo menos 1.8 com uma diferença principal:

Em vez de ter propriedades typescript.main e typescript.definition , há apenas uma propriedade typings que você pode apontar para um arquivo d.ts ou um .ts normal

Se você está desenvolvendo um módulo para usar apenas localmente, você pode ter o typings apontando para um arquivo .ts , mas se você planeja publicar o módulo, é recomendado que ele aponte para um arquivo d.ts . Isso ocorre porque você não quer que seus consumidores de módulo recompilem seus arquivos de módulo, apenas consumam suas tipagens.

Eu configurei um exemplo de uso disso aqui:
https://github.com/chanon/typescript_module_example

Há uma página de documentação aqui que tem mais informações:
http://www.typescriptlang.org/docs/handbook/typings-for-npm-packages.html

Obrigado aos desenvolvedores do TypeScript e a todos os contribuidores.

O problema original/solicitação de recurso segue


Motivação

No TypeScript, é muito mais difícil reutilizar módulos TypeScript em comparação com a reutilização de módulos npm em JavaScript.

Seria benéfico se o compilador typescript fosse inteligente o suficiente para procurar nas pastas node_modules e nos arquivos package.json.

O motivo é que os desenvolvedores de módulos npm que usam TypeScript podem começar a escrever e distribuir módulos por meio do próprio npm. O TypeScript seria capaz de pegar carona na infraestrutura do npm e no amplo suporte.

Exemplo para node_modules

Se tivéssemos:

./node_modules/concator/index.ts
./myApp.ts

E no index.ts tivemos:

export function concat(param1: string, param2:string): string {
      return param1 + ' ' + param2;
}

em myApp.ts:

import concator = require('concator');  // loads the module from node_modules
var result = concator.concat('I like', 'this.');
var wontWork = concator.concat('this will fail');  // compile error, concat needs 2 params

Então, basicamente, o compilador é inteligente o suficiente para encontrar o módulo em node_modules e usa automaticamente a versão do typescript (index.ts).

Então, quando o código é compilado para JavaScript, ele naturalmente usa a versão JavaScript.

Importando pastas como módulos

Um caso mais básico é o suporte à regra popular do Node.js de http://nodejs.org/api/modules.html#modules_folders_as_modules como sugerido por @vvakame abaixo e na edição #207 fechada (semi-duplicada).

typescript.main em package.json

Pode haver uma adição aos arquivos package.json para especificar onde está o arquivo .ts principal de um módulo npm do TypeScript. Isso seria semelhante à chave main que especifica onde está o arquivo JavaScript / .js principal, mas para o TypeScript.

Por exemplo, package.json para um módulo npm chamado "myModule" localizado em node_modules/myModule/package.json

{
     "main": "./dist/index.js",
     "typescript": {
          "main": "./src/index.ts"
     }
}

Neste exemplo node_modules/myModule/src/index.ts seria o arquivo TypeScript principal e fazer um import myModule = require("myModule"); importaria o arquivo node_modules/myModule/src/index.ts .

Para um codificador JavaScript escrevendo var myModule = require("myModule"); em um arquivo JavaScript, o require carregaria o arquivo node_modules/myModule/dist/index.js como de costume.

Como pode ser visto neste exemplo, o TypeScript src está na pasta node_modules/module-name/src e os arquivos JS compilados estariam em node_modules/module-name/dist .

Algo assim pode ser um (semi) padrão para módulos npm do TypeScript para que a fonte do TypeScript seja separada de forma limpa da saída JavaScript compilada.

Um caso mais básico, como sugerido por @vvakame abaixo, é o suporte à popular regra Node.js de http://nodejs.org/api/modules.html#modules_folders_as_module

typescript.definition em package.json

Outra chave possível para package.json para módulos npm não-TypeScript (javascript simples) poderia ser typescript.definition . Isso apontaria para um arquivo .d.ts que define o módulo para usuários do TypeScript do módulo npm.

Para que um
import $ = require('jquery');
leria automaticamente um arquivo jquery.d.ts definido na chave typescript.definition no package.json do jQuery e tornaria $ o tipo correto.

Exemplo de formato:

{
     "main": "./dist/index.js",
     "typescript": {
          "definition": "./index.d.ts"
     }
}

(Este formato já é usado pelo tsd como @Bartvds explica abaixo.)

Então nós, codificadores TypeScript, teríamos que tentar obter o máximo de mantenedores do módulo npm não-TypeScript para mesclar nossos pull requests que têm nossos arquivos .d.ts e chaves typescript.definition package.json.

Se formos bem sucedidos com isso, então a vida dos codificadores TypeScript seria uma benção... não mais gerenciamento separado de arquivos .d.ts Definitivamente Typed. Basta instalar o npm e você também obterá suas definições do TypeScript! Automaticamente e atualizado com a versão do módulo instalado.

Lista de Benefícios

O que obtemos de tudo isso é

  • Os módulos npm podem ser escritos em TypeScript.
  • Ambos os codificadores TypeScript e JavaScript podem usar esses módulos
  • Os usuários do módulo que usam o TypeScript obtêm os benefícios da digitação estática sem que o codificador do módulo (ou usuário) tenha que usar o método usual de escrever (ou gerar) arquivos .d.ts separados (portanto, quando o código-fonte do módulo já estiver no TypeScript não precisamos ter outro arquivo .d.ts para manter)
  • Haveria uma maneira de reutilizar e distribuir facilmente módulos TypeScript usando npm com o qual todos já estão familiarizados
  • Isso pode ajudar a promover o próprio uso do TypeScript, pois os codificadores JavaScript que usam os módulos npm escritos em TypeScript podem ver o quão boa / melhor é a fonte do TypeScript e tentar mudar para ela. Ou eles podem querer contribuir para o módulo e, como a fonte está em TypeScript, eles teriam que aprendê-lo, o que pode levá-los a gostar e decidir usá-lo em seus próprios projetos.
  • Basicamente, isso ajudaria a aumentar a comunidade TypeScript por meio de todo o compartilhamento de código que poderia resultar. No momento, o código TypeScript de todos é principalmente seu / em seu próprio silo. Na verdade, isso é provavelmente uma coisa extremamente importante, pois não ter uma maneira adequada/fácil de compartilhar/distribuir/reutilizar módulos provavelmente está limitando o crescimento da linguagem. [1]
  • A reutilização de módulos em projetos internos seria muito menos trabalhosa e reduziria a necessidade de todos esses caminhos relativos para arquivos .d.ts e caminhos relativos em módulos obrigatórios e coisas gerais .d.ts. (Neste momento, ao escrever código TypeScript, acho que tenho que aprender a ser bom em contar ../../ s)
  • Essa abordagem também suporta Browserify/Webpack como Browserify/Webpack também procura em node_modules, então isso permite módulos TypeScript reutilizáveis ​​/ npm distribuídos facilmente para o servidor e o navegador
  • Módulos npm não TypeScript podem ser facilmente usados ​​no TypeScript com informações de tipo por meio da adição de chave typescript.definition . Isso permite que os arquivos de definição .d.ts sejam empacotados junto com o módulo npm para que a atualização de um módulo npm atualize automaticamente seu arquivo de definição .d.ts. Isso elimina a necessidade de atualizar os arquivos .d.ts manualmente.
  • Usar arquivos de definição através do typescript.definition é mais simples porque é simplesmente uma instrução import moduleName = require("moduleName") sem a necessidade de um ///<reference ... separado
  • O uso de arquivos de definição por meio do typescript.definition também deve permitir o uso de diferentes versões do módulo na mesma base de código sem conflitos de nomes de tipo.

Proposta detalhada

@Nemo157 escreveu uma proposta muito detalhada de como tudo isso deve funcionar em:

TypeScript proposto requer semântica de resolução
https://gist.github.com/Nemo157/f20064a282ee620f3877

Uma adição na proposta é o uso de pastas /typings que podem conter arquivos de definição que podem ser gerenciados automaticamente por ferramentas como tsd para módulos JavaScript npm que não incluirão arquivos de definição em seus repositórios .

Fatos de Apoio Finais

Como o TypeScript compila para JavaScript que é executado principalmente em dois locais: node.js e em navegadores, o suporte a node_modules é benéfico para ambos os locais (praticamente todos onde o TypeScript é usado) por causa do npm e do Browserify/Webpack.

ou seja. não há razão para criar um esquema diferente quando node_modules é o que todos os usuários do TypeScript já usam para talvez 75%-100% de todo o código JavaScript. (Tirando 25% para talvez usuários do RequireJS.)

Notas de rodapé

[1] - BTW, vejo que existe um gerenciador de pacotes NuGet (?) da Microsoft que pode distribuir módulos typescript (?), mas vindo de um plano de fundo focado em node.js (não focado em .NET), não vejo o NuGet se tornando amplamente usado fora das lojas focadas na Microsoft, especialmente porque npm é o padrão para node.js e também é um padrão líder para JavaScript do lado do cliente. Se eu não usasse o TypeScript, nunca teria ouvido falar do NuGet. O codificador JavaScript do lado do node.js/cliente médio provavelmente preferiria usar o npm, a mesma ferramenta que eles já usam, em vez de ter que usar algo específico da Microsoft, como o NuGet. (Na verdade, não sei nada sobre o NuGet, então o que estou dizendo aqui pode não importar.)

Committed Suggestion

Comentários muito úteis

De qualquer forma, o compilador atualmente afirma que não consegue encontrar o módulo, quando na verdade está apenas se recusando a importar o módulo sem definição de tipo. Isso não é realmente útil, é?

Todos 138 comentários

[movido para typescript.main em package.json na descrição do problema acima]

:+1:
Eu acho que http://nodejs.org/api/modules.html#modules_folders_as_modules é uma regra muito popular do Node.js.

outro exemplo.

./test/index.ts

export function hello() { return "Hello, world"; }

./main.ts

import test = require("./test/");
console.log(test.hello()); // print "Hello, world"

[movido para typescript.definition em package.json na descrição do problema acima]

Uma solução seria resolvê-lo com melhores ferramentas. Por exemplo import foo = require('foo') lhe dá uma dica para procurar algum node_module+package.json local (foo é um projeto ts) ou definição DT (foo é um projeto js onde os autores da biblioteca não querem manter o ts def) .

PARA SUA INFORMAÇÃO; Na verdade, estou testando algo semelhante a isso no TSD; uma maneira de expor e vincular definições que são empacotadas nos pacotes npm (ou bower).

Está na minha versão dev para 0.6 e funciona adicionando um elemento typescript ao package.json (ou bower.json), com um subelemento definition (um subelemento porque talvez um dia haveria source também, ou qualquer outra coisa).

{
    ...
    "main": "./index.js",
    "typescript": {
        "definition": "./foo.d.ts"
    }
    ...
},

Em seguida, você pode executar um comando no TSD, atualmente tsd link e ele verificará todos os arquivos package.json em node_modules (ou bower ou qualquer outro), encontre essa propriedade se definida e adicione uma referência a ela ao tsd.d.ts central

Exemplo: definido aqui e use aqui

@Bartvds Isso é muito bom. Pode ser o primeiro passo para ter .d.ts em pacotes npm. Gosto da estrutura package.json com "definition" em "typescript", é bem mais organizada.

Se o próprio compilador TypeScript pudesse lê-lo automaticamente, seria muito legal.

Marcar isso para discussão -- resolução de módulo externo mais inteligente é algo sobre o qual precisamos falar para entender os vários cenários aqui. Isso foi mencionado anteriormente e fizemos alguns ajustes na versão 1.0.

Discuta também o nº 207 - procurando em 'índice'

:+1:

@chanon tsMain não é necessário se usarmos a geração de declarações.

Sim, o problema é imensamente importante mesmo para navegadores - muitos projetos usam browserify/packify e, portanto, layouts de diretório compatíveis com nós

:+1:

Já houve algum trabalho nessa área no repositório do codeplex, um pull request de leebyron e outro de kayahr .

Eu tenho pensado em tentar portar um deles para o novo repositório, mas parece que o código relacionado foi muito reorganizado.

Eu escrevi uma proposta de como adicionar isso ao compilador TypeScript . Isso também inclui procurar no diretório typings , pois isso será importante ao trabalhar com módulos javascript que não manterão suas próprias definições de typescript. Infelizmente, fazer tudo isso funcionar de forma transparente com tsd ainda vai dar um pouco de trabalho, pois a exigência de /// <reference d arquivos serem declarações externas de ambiente torna as coisas um pouco complicadas. Vou dar uma olhada na implementação disso em uma ramificação e fornecer alguns módulos de exemplo usando-o.

Parece sensato. Isso cobrirá módulos com dependências de tipo conflitantes? Quero dizer, se um aplicativo importa A e B, e B também depende de A. É fácil cair em erros de tipo duplicado se houver duas cópias das declarações externas.

Não deveria, eles devem resolver para diferentes nomes de módulos externos, então declare tipos independentes com nomes idênticos em módulos diferentes. A verificação do tipo estrutural deve permitir que os diferentes módulos interajam sem problemas.

Esse é um dos principais problemas com as definições atuais de tsd que isso está tentando resolver, definindo módulos de ambiente externos, não há como lidar com várias versões de uma biblioteca com nomes idênticos, mas tipos ligeiramente diferentes .

@joewood também haverá problemas entre diferentes versões de A

├── [email protected]
└── [email protected]
    └── [email protected]

não há como eles lidarem com várias versões de uma biblioteca com nomes idênticos, mas tipos ligeiramente diferentes.

interessados ​​em ouvir soluções para o mesmo. O TypeScript tem um escopo de variável de nível global para declarações de ambiente

Mesmo que as versões correspondam, no momento vejo problemas com dois arquivos de declaração de ambiente diferentes, mas correspondentes, causando erros de símbolo duplicados. A diretiva /// reference definida localmente precisa de alguma forma resolver de volta para um único arquivo. Ou isso, ou a identidade do tipo precisa incluir o caminho e a tipagem estrutural cuidará das incompatibilidades de versão etc.

@joewood Sim, espero que seja corrigido na maioria dos casos alterando require para carregar as definições corretas, evitando /// reference sempre que possível. Os módulos externos serão identificados por seus caminhos absolutos em vez de ter declarações de ambiente, portanto, deve ser possível carregar vários do mesmo nome de diferentes caminhos e em diferentes versões.

Sim, é o que espero que seja corrigido na maioria dos casos alterando require para carregar as definições corretas, evitando /// referência sempre que possível.

:+1:

:+1: Obrigado @Nemo157 e a todos pela discussão.

Atualizei o texto do problema principal para mesclar as adições de package.json e vinculei à proposta de @Nemo157 .

:+1:

Eu fiz uma implementação inicial da minha proposta junto com a criação de um conjunto de módulos de exemplo para mostrar que todas as diferentes maneiras de fazer um módulo funcionarão. Incluindo o uso de diferentes versões da mesma biblioteca em diferentes submódulos.

:+1:

Pastas como módulos com index.ts :+1:

:+1:

:+1:

:+1:

:+1:

:+1: :+1: :+1:

:+1: :+1: :+1: :+1:

Comentando para trazer isso de volta ao nosso radar.

Eu tive um bom sucesso com a sugestão do @Bartvds :

Em seguida, você pode executar um comando no TSD, atualmente o link tsd e ele verificará todos os arquivos package.json em node_modules (ou bower ou qualquer outro), encontre essa propriedade se definida e adicione uma referência a ela no pacote central tsd.d.ts no seu projecto.

Então, definitivamente, considere apoiar typescript em package.json , pois foi assim que a comunidade foi.

Definitivamente, precisamos que o tsc esteja ciente da pasta node_modules se o TypeScript for amplamente usado na comunidade node.js. Atualmente uso links simbólicos para módulos que fazem parte do meu projeto de desenvolvimento (usando npm-workspace), e tenho duas opções no momento:

  • importe diretamente de node_modules, que parece errado: import Foo = require("node_modules/mymodule/Foo");
  • obtenha tsc para gerar os arquivos de declaração e, em seguida, junte-os usando um arquivo de declaração de módulo mantido manualmente que alterna os nomes dos módulos de string

O tsc poderia verificar o nome do módulo externo nas declarações de importação e, durante a resolução do caminho, também aplicar node_modules da mesma maneira que o tempo de execução do node.js? Uma opção do compilador também pode ativar ou desativar isso.

:+1: :+1: :+1:

Poderia tsc verificar o nome do módulo externo nas declarações de importação e, em seguida, durante a resolução do caminho, também aplicar node_modules da mesma maneira que o tempo de execução node.js faz

Assim é como deve ser. A maneira atual de apenas procurar na árvore de diretórios para encontrar um arquivo com o referido nome não tem nenhuma semelhança com os contextos de execução JS.

Este já está na minha lista há algum tempo. tentará obter isso na próxima versão.

Nós ( Booktrack ) usamos TypeScript para todo o nosso desenvolvimento web e enfrentamos desafios semelhantes aos desenvolvedores do node.js. Eu falo porque a voz dos desenvolvedores da web não parece tão alta quanto a dos desenvolvedores do nó.

Soluções (em ordem de pior para nós para melhor para nós):

  1. resolução de nomes de módulos externos de nível superior por meio de pesquisa codificada em node_modules
  2. sem controle sobre a resolução de nomes de módulos externos de nível superior
  3. um sinalizador do compilador para controlar a resolução opcional de nomes de módulos externos de nível superior no diretório node_modules
  4. um parâmetro de "caminho(s) de pesquisa de módulo" do compilador para controlar a resolução opcional de nomes de módulos externos de nível superior no(s) caminho(s) fornecido(s)
  5. um parâmetro "module resolver" do compilador para fornecer ao compilador um plug-in JS que resolverá todos os nomes de módulos externos (não apenas de nível superior)
  6. ganchos apropriados em serviços de linguagem de modo que a resolução do nome do módulo externo seja controlável

A opção 1 é terrível, prefiro a opção 2.

As opções 5 e 6 permitiriam usos exóticos de instruções de importação, como aquelas encontradas ao trabalhar com plugins requirejs ou webpack. A ideia básica: o compilador delega todas as pesquisas de nome de módulo externo (não apenas de nível superior) a um terceiro (um plugin ou retorno de chamada). O delegado, dado o caminho para o módulo em compilação e o nome do módulo externo, retorna ao compilador o caminho do sistema de arquivos OU as informações de tipo para o nome do módulo fornecido.

Eu ficaria feliz se a opção 4 fosse implementada, feliz se a opção 6 fosse implementada e muito feliz se a opção 4 e a opção 6 fossem implementadas.

Que tal um --basePath para sua raiz de pesquisa de módulo, todas as importações de módulo serão observadas em relação a esse caminho. Isso se aplica apenas para AMD.

Acho que o problema do nó é muito mais simples, só precisamos implementá-lo :)

Observe que, na verdade, obtivemos uma implementação (e testes) de @Nemo157 aqui há muito tempo https://github.com/Microsoft/TypeScript/issues/247#issuecomment -57422329

Concordo com @mark-buer e @mhegazy , a opção 4 de um caminho de pesquisa deve ser uma correção simples. Uma solução mais elaborada no serviço de idiomas (opção 6) é definitivamente necessária a longo prazo.

_Vale a pena adicionar_: isso por si só não corrigirá o problema de reutilização do TypeScript no npm devido ao problema de símbolo duplicado para referências de tipo comuns #1125. Nós realmente precisamos evitar ///usando arquivos .tsconfig e conserte isso corretamente agrupando pacotes em um único módulo de tipo externo, conforme sugerido em #17

Outro voto para obter a pasta node_modules reconhecida pelo compilador typescript.

Para módulos CommonJS, o typescript deve, idealmente, seguir a mesma resolução de nome de arquivo que require.resolve (conforme descrito pelo psuedocode nesta página: http://nodejs.org/api/modules.html#modules_all_together.

essa funcionalidade é crítica para permitir a integração do compilador typescript em outros empacotadores de nós, como o browserify. O patch do @Nemo157 faz um bom trabalho, mas não permite testes fáceis com os empacotadores existentes, pois a maioria mudou para versões posteriores do texto datilografado e não é mais compatível com seu código

Onde o diretório node_modules deve estar em relação às fontes?

Atom-TypeScript agora suporta typescript.definition pronto para uso. Detalhes: https://github.com/Microsoft/TypeScript/issues/2829

Você também pode criar esses pacotes facilmente usando o atom-typescript :rose: novamente veja #2829

Limitação

Funcionará _perfeitamente_ se você compartilhar um pacote que não dependa de nenhuma biblioteca externa. Se isso acontecer, precisamos de um algoritmo de resolução de conflitos de módulo.

Estou aberto a sugestões para este caso, mas meu plano é:

  • fazemos algumas coisas inteligentes ao ler um d.ts não dando ao TypeScript os comentários externos reference (por exemplo, node.d.ts aqui https://github.com/TypeStrong/atom-typescript-examples /blob/master/node/node_modules/example-typescript-b/definition/sample-bdts) E, em vez disso, apontar para o nosso próprio .d.ts se o tivermos em nosso Typings.

Isso vai ficar no caminho certo para 2.0? Parece ser um recurso importante para a adoção do Node.js, que agora é doloroso, mesmo com o FixedTyped e similares.

Parece ser um recurso importante para a adoção do Node.js, que agora é doloroso, mesmo com o FixedTyped e similares.

@LPGhatguy Consulte https://github.com/Microsoft/TypeScript/issues/2338. @vladima está trabalhando nisso, mas não acho que tenha sido atribuído nenhum marco ainda :rose:

@LPGhatguy , estamos tentando obter isso na próxima versão. espero que em breve.

@mhegazy Você quer dizer 1,6? Isso seria incrível!

Isso está relacionado ao #2338?

sim para TypeScript 1.6 (pelo menos é isso que estamos tentando fazer), sim para #2338; há algumas outras mudanças e problemas em torno disso, incluindo #3147 e #4154

Então, por que é marcado como TypeScript 2.0 como um marco?

obrigado @heycalmdown , removeu o marco. geralmente não marcamos marcos para sugestões. Espero que tenhamos uma atualização dentro de uma semana ou mais sobre esse problema. Fique ligado.

Eu gostaria de pedir suporte ao módulo ES6 para seguir isso também (o que eu suponho que seria?)

Digitação para

import mylib = require('mylib');
mylib.foo(mylib.bar);

deve se comportar da mesma forma que

import { foo, bar } from 'mylib';
foo(bar);

Eu gostaria de pedir suporte ao módulo ES6 para seguir isso também (o que eu suponho que seria?

@DavidSouther Esse seria _automaticamente_ o caso. A pesquisa entre os dois é consistente :rose:

isso é tratado por #4154.

Se eu estiver usando todas as noites, a partir de amanhã, devo esperar que a importação de módulos de nó "simplesmente funcione"?

Pergunta:
Eu acho que é uma convenção comum ter arquivos nomeados
"index" em commonJS e
"principal" em AMD
para caminhos curtos.
Na pergunta em cima o autor importa
/node_modules/concator/index.ts como
import concator = require('concator');

Por favor, perdoe-me - atualmente estou descobrindo se também a resolução do índice é suportada agora e que tal index.ts ou main.ts na AMD requer resolução?
Também estou pingando @basarat para saber se é / será suportado por https://github.com/TypeStrong/atom-typescript porque agora ele não me permite exigir nenhum index.ts como mencionado acima.

@sebilasse , se você estiver usando typescript@next hoje, isso deve funcionar com --module commonjs

import concator = require('concator'); // resolves to node_modules/concator/index.ts

Não há alterações na resolução da AMD em relação às versões anteriores.

@DavidSouther deve estar em typescript@next hoje. experimentá-lo e deixe-nos saber como ele se sai.

@mhegazy @basarat :+1: ok. Mas como você pensa sobre a resolução AMD para main.ts ou index.ts - não deveria ser consistente no futuro?

@sebilasse , para AMD, acho que precisamos fazer algo conforme observado por @vladima em # 2338 (seção para: carregador de módulo RequireJS/ES6).

Muito agradável!! \o/

@mhegazy Ainda não está funcionando como eu esperava.

Eu juntei https://github.com/DavidSouther/typescript-example-using-node com meu caso de uso "ideal". tslib é uma biblioteca simples que exporta uma única função. tsclient depende de tslib, assim como readline dos pacotes Node. O script de configuração é conveniente para instalar, vincular e executar. Incluí uma corrida e anotei as partes inesperadas com comentários embutidos.

% ./setup
...
> [email protected] build ~/ts-node/tslib
> tsc --version ; tsc -p src/

message TS6029: Version 1.7.0-dev.20150831
...
> [email protected] build /Users/southerd/devel/tmp/ts-node/tsclient
> tsc --version ; tsc -p src/

message TS6029: Version 1.7.0-dev.20150831
# Expect this to find tslib, but fail type checking.
# See tsclient/app.ts for details
src/app.ts(4,21): error TS2307: Cannot find module 'tslib'.

+ node ./dist/app.js # This works as expected!
What would you ask? What is the meaning of life?
42
+ set +x

Também não estou recebendo suporte de idioma para importações tslib no tsclient (VSCode versão 0.7.0 (0.7.0)), embora não tenha certeza de qual TSC está usando ou como alterar isso.

O compilador @DavidSouther TypeScript verifique o campo 'typings' em package.json para encontrar arquivos '.d.ts'. Com essa alteração estou recebendo src/app.ts(13,7): error TS2322: Type 'string' is not assignable to type 'number'. que parece um erro legítimo

Ah, eu devo ter perdido aquele pedaço de documentos. Ainda estou tendo o segundo problema - como altero a versão do VSCode tsc?

você pode fornecer o local personalizado do SDK do TypeScript para o VSCode por meio da configuração "typescript.tsdk" - ele deve apontar para a pasta que contém tsserver.js e arquivos '.d.ts' padrão. Caso o TypeScript esteja instalado como pacote npm, será algo como

// Place your settings in this file to overwrite the default settings
{   
    "typescript.tsdk": "C:\\Sources\\bugs\\node\\typescript-example-using-node\\tslib\\node_modules\\typescript\\lib"       
}

Alguém conseguiu uma amostra funcionando? Tentei a tarde inteira brincar com isso, mas sempre acabo com

error TS2307: Cannot find module

No momento o código está em node_modules/my-module/. E eu defini um index.ts que cuida de exportar tudo, e eu o referi no package.json em typescript.main. No projeto do consumidor tentei importar {AClass} de 'my-module'; e import meu-módulo = require('meu-módulo'); Ambos levam ao mesmo erro com o typescript 1.7.0-dev.20150901.

Ao resolver um módulo com nome não relativo, com --module commonjs , o compilador procurará um .d.ts que corresponda ao nome em node_modules\name\index.d.ts ou procurará em package.json para uma propriedade typings e carregue os .d.ts para os quais ela aponta.

da sua descrição, parece que você está configurando para index.ts , você realmente não quer compilar suas dependências, você só quer consumir suas tipagens, então você deve configurá-lo para index.d.ts .

Atualizei as etapas no algoritmo de resolução do módulo do nó para refletir a implementação: https://github.com/Microsoft/TypeScript/issues/2338

@DavidSouther , aparentemente, tenho exatamente o mesmo problema. Quando compilo com uma dependência em node_modules, ele não consegue resolver o módulo e gera um erro, mas ainda gera o js e, se eu executá-lo, ele executa. Talvez seja devido à minha configuração que eu não sei. Meu d.ts está praticamente vazio, tenho um index.ts que se encarrega de importar e reexportar todas as classes dos meus módulos definidos em muitos arquivos .ts. E então meu arquivo d.ts apenas faz referência a este index.ts e exporta tudo de index.ts assim:

/// <reference path="index.ts" />

declare module 'my_module' {
    export * from 'index';
}

Além disso, de alguma forma ainda compila o ts de node_modules, portanto, devo adicionar uma tarefa limpa para excluí-lo após a compilação. Existe uma descrição do recurso em algum lugar que resume o processo?

edit: Consegui funcionar, mas é super hacky e ainda gera erros. Criei um d.ts com dts-generator, e então importei minhas classes assim:

import MyClass from '../../node_modules/my_module/dist/MyClass';

Se eu usar import MyClass de 'my_module/MyClass' eu consigo compilar sem erro, mas em tempo de execução recebo o erro não pode encontrar o módulo 'my_module/MyClass'. Com a solução acima, ele aponta diretamente para o .js compilado e, em tempo de execução, funciona de alguma forma, mesmo que produza o erro não pode encontrar o módulo em tempo de compilação.

Ainda tendo problemas para importar de submódulos (por exemplo, npm install angular2, import { Inject, Binding } from 'angular2/di' . Trabalhará para obter um caso de teste contido esta noite.

Não pense que o angular já agrupa suas tipagens da maneira esperada pelo compilador TypeScript.

Isso é provavelmente verdade; Vou trabalhar com eles e ver onde isso vai parar.

esse recurso está funcionando bem no typescript 1.1 , por exemplo https://github.com/Nemo157/typescript_w_node_modules_example

mas falha no typescript 1.5.3, alguma coisa mudou?

------ atualizar ---------

Eu sei que será lançado em 1.6, obrigado

Eu só consigo esse "meio trabalho" em 1.6.2

Primeiro, empacoto uma biblioteca com um my-lib.d.ts no diretório dist e aponto para este arquivo no atributo package.json arquivo typings (por exemplo "typings" : "dist/my-lib.d.ts" )

Então eu importo esta biblioteca em um arquivo TypeScript Test.ts usando

import { MyObject } from "my-lib"

MyObject é importado corretamente e o código js é emitido na transpilação.
O Visual Studio Code ainda fornece conclusão em MyObject

No entanto, recebo avisos do compilador que:
Test.ts(10,60): error TS2306: File '[]/node_modules/my-lib/dist/my-lib.d.ts' is not a module.

O Visual Studio Code realmente mostrará a importação como um erro difícil

Quaisquer módulos importados de um pacote de nó precisam ser "módulos externos" e não "declarações de módulo ambiente". ou seja, não há declarações declare module "foo" {.. } , mas sim, declarações de importação ou exportação de nível superior no arquivo.

Portanto, se o seu pacote "my-lib" estiver escrito em typescript, apenas construa-o com --declarations e defina as tipagens para o arquivo .d.ts do seu módulo principal. se não, e suas digitações são algo que você criou à mão, ou obteve definitivamente digitado, então você precisará alterá-lo para um módulo externo ou esperar até que o #4665 seja resolvido (espero que em breve).

O motivo dessa restrição é que isso pode causar poluição de escopo global e conflitos mais tarde para os usuários do pacote. há uma longa discussão sobre isso em #4665.

Aqui está alguma documentação para pesquisas futuras: https://github.com/Microsoft/TypeScript/wiki/Typings-for-npm-packages

@mhegazy Obrigado por sua resposta rápida que realmente ajudou na minha busca para automatizar a construção de bibliotecas commonjs, escritas em Typescript, que podem ser consumidas por código Javascript e TypeScript.
A sintaxe e a resolução de import/export estão se movendo tão rápido recentemente que o que eu acho que está faltando agora é um guia definitivo sobre como construir um.

Eu consegui funcionar ... com uma ressalva (e, portanto, outra pergunta)

Aqui está uma visão simplificada da configuração.

A biblioteca é composta por três objetos A1, A2 e B em 2 arquivos datilografados A.ts e B.ts; algo como

fontes

A.ts

class A1{}
class A2{}
export { A1, A2 }

B.ts

class B{}
export { B }

O que queremos expor é coletado em um index.ts :

export * from './A'
export * from './B'

Construir
A compilação é conduzida com a ajuda do grunt e os sinalizadores --module commonjs e --declaration são definidos em tsc 1.6.2
O resultado final da construção é uma árvore que se parece com

    package.json
    dist/
        js/
             A.js
             B.js
             index.js
        typings/
             A.d.ts
             B.d.ts
             index.d.ts

package.json contém estas duas entradas:

"main": "dist/js/index.js",
"typings": "dist/typings/index.d.ts"

Usar esta biblioteca no TypeScript 1.6.2 com um simples import {A1, A2, B} from "mylib" funciona perfeitamente. Dependências de vários níveis (ou seja, bibliotecas importando umas às outras) também funcionam bem.

Onde surgem problemas é quando a biblioteca depende de outra biblioteca que _não_ é uma biblioteca TypeScript.
Digamos que a biblioteca dependa do Node.js.
Em um dos arquivos de origem haverá uma referência às tipagens do NodeJS, por exemplo
///<reference path="../typings/node/node.d.ts"/>

Após a transpilação, essa instrução <reference > vai acabar no arquivo de declaração correspondente; o problema é que o caminho para node.d.ts provavelmente está errado ou inexistente.
Existe uma maneira recomendada de fazer isso?

_Nota_: este problema é amenizado pelo uso de um arquivo index.ts para expor as partes interessantes da biblioteca, já que index.ts não tem motivos para conter uma instrução <reference > e com 1.6 .2, o compilador não parece se importar que Adts tenha um caminho inválido na instrução de referência

@bgrieder Lidamos com isso em Phosphor usando tsconfig.json :
https://github.com/phosphorjs/phosphor-widget/blob/master/src/tsconfig.json

Nós simplesmente adicionamos quaisquer tipagens externas que precisamos aos arquivos compilados. Isso significa que, se algum desses tipos externos fizer parte de nossa interface pública, os consumidores do código também precisarão fornecer esses tipos externos como parte de sua compilação. _Esta certo_. Se fôssemos empacotar essas definições, e alguma outra lib usada pelo consumidor _também_ empacotasse essas mesmas definições, haveria conflitos de símbolos duplicados.

@sccolbert Sim!
Eu estava preocupado que a remoção de instruções <reference ...> quebraria o preenchimento automático em todos os IDEs, mas ei, não: pelo menos o Visual Studio Code 0.8.0 parece ser inteligente o suficiente para escolher essas definições do tsconfig.json arquivo ! (após um reinício)

Feito com reference . Excelente !

@sccolbert

E se você estiver usando um projeto simples Node.js dentro dele e *.d.ts para ele, como a solução tsconfig o ajuda?

@heycalmdown você acabou de adicionar o d.ts ao campo files no tsconfig , aqui está um exemplo que faz isso:

https://github.com/phosphorjs/phosphor-widget/blob/master/test/src/tsconfig.json#L11
https://github.com/phosphorjs/phosphor-widget/blob/master/test/src/index.ts#L10

Observe que temos que usar require aqui em vez de import apenas por causa de como o arquivo d.ts para expect.js é escrito internamente.

OK eu entendi. Seus repositórios parecem um bom exemplo.

Isso realmente foi implementado no TypeScript 1.6.2?

Se tiver, alguém pode me dizer o que estou fazendo de errado aqui?:
https://github.com/chanon/typescript_module_example

Você provavelmente quer a sintaxe de importação es6.

Em quarta-feira, 4 de novembro de 2015, 6h10, chanon [email protected] escreveu:

Isso realmente foi implementado no TypeScript 1.6.2?

Se for, alguém pode me dizer o que estou fazendo de errado aqui?:
https://github.com/chanon/typescript_module_example


Responda a este e-mail diretamente ou visualize-o no GitHub
https://github.com/Microsoft/TypeScript/issues/247#issuecomment -153688004
.

Acabei de atualizá-lo para usar a sintaxe de importação es6 e ainda recebo os mesmos erros (não é possível encontrar o módulo).

@chanon os pacotes package.json para node_modules precisam ter uma chave typings que aponta para um arquivo d.ts , _não_ uma chave typescript apontando .ts arquivos como você tem agora.

Usamos a resolução de módulos de nó exclusivamente no PhosphorJS (no TS 1.6.2) e funciona bem. Aqui está um exemplo: https://github.com/phosphorjs/phosphor-widget/blob/f908341cb1d46ada8ad8149e695a75e7ea2fde57/package.json#L6

Obrigado @sccolbert , no entanto, minha proposta inicial (no início desta edição) era permitir uma propriedade typescript.main em package.json que apontaria para o ponto de entrada principal do TypeScript para pacotes de módulos de nó escritos em TypeScript.

Isso permitiria a importação de módulos TypeScript no código TypeScript sem a necessidade de arquivos de digitação d.ts (não haveria necessidade de gerá-los).

@chanon Eu estava apenas apontando o que você precisa fazer para executar seu código.

@sccolbert , vejo obrigado.

Alguém que saiba pode me dizer se devo criar outro problema solicitando esse recurso específico?

Os principais problemas relacionados à lógica de resolução de módulo (além deste) parecem ser #2338, que está fechado, e #5039, que parece ser sobre suporte à resolução de caminho no estilo SystemJS, que parece muito complexo.

No entanto, apenas a importação simples do estilo CommonJS, como solicitado inicialmente nesta edição, parece ter sido esquecida? Pelo menos a parte sobre typescript.main e pastas como módulos?

Eu não entendo a necessidade de ter (e desejo ter) arquivos d.ts se tanto o módulo quanto o consumidor do módulo já estiverem escritos em TypeScript.

Na verdade, não é muito diferente de importar um arquivo TypeScript relativamente ex.

Em vez de ter que fazer:
import * as lib from '../relative/path/to/typescriptFile.ts'

Ou:
import * as lib from '../../node_modules/myModule/index.ts'

Apenas deixe o TSC ser capaz de encontrar o arquivo typescript para importar usando a resolução normal do caminho node_modules. E pelo menos permitir a importação de pastas como módulos (com um index.ts) para que no segundo exemplo eu pudesse fazer:

import * as lib from 'myModule'

Ou é por causa de "você realmente não quer compilar suas dependências, você só quer consumir suas tipagens"?

@chanon o comportamento que você descreve é ​​o que está no mestre agora. você pode tentar typescript@next ?

a implementação original do #2338 adicionou algumas verificações extras para garantir que seja um .d.ts, e isso é principalmente pelo motivo que você mencionou. você não quer que os usuários do seu pacote compilem suas "fontes" em cada chamada do compilador e obtenham uma saída diferente com base nas opções do compilador, você deseja apenas compartilhar suas digitações.

No entanto, se você estiver construindo os dois pacotes, talvez queira fazer isso enquanto itera neles. A restrição foi removida em #5278.

Por favor, dê uma olhada na página wiki para compartilhar digitações através do pacote npm para mais informações: https://github.com/Microsoft/TypeScript/wiki/Typings-for-npm-packages

Obrigado pelo seu esclarecimento @mhegazy! Vou testá-lo.

@mhegazy Acabei de tentar com typescript@next , funciona como esperado!

Isso é ótimo!!

E obrigado a todos por participarem deste e de outros assuntos relacionados :+1:

Adicionei uma atualização ao texto do problema acima para explicar como esse recurso foi realmente implementado.

Correndo o risco de entrar em um campo minado, como isso deve funcionar com módulos npm simples que _não_ têm uma propriedade typings em package.json? Tentar usar tape ou get-parameter-names com typescript@next faz com que ele exploda na minha cara, pois não é possível encontrar esses pacotes devido ao fato de eles não terem isso propriedade.

Claro, eles não são módulos datilografados, mas não consigo encontrar uma solução alternativa e isso bloqueia uma parte significativa do ecossistema npm.

@danpantry Normalmente você usaria um arquivo .d.ts normal escrito especificamente para aquele módulo. O projeto Definitivamente Typed possui arquivos .d.ts para vários módulos comuns. Existe um utilitário tsd que pode ajudar a instalar e gerenciar arquivos .d.ts do Definitivamente Typed para você.

Você pode usar módulos normais sem digitar apenas usando a sintaxe normal do commonjs require.

por exemplo
var moduleName = require("moduleName")

@chanon parece um truque para usar a sintaxe 'clássica' require ao usar a sintaxe ES6 com TypeScript para que eu possa usar dependências JavaScript, mas obrigado. Ouvi falar do utilitário tsd, mas não tenho certeza de como isso afetaria o uso de importações ES6 .. a menos que eu tenha que começar a usar /// <reference path=... para esses tipos de módulos?

Sim, esse é um caminho. Outra maneira é usar os arquivos tsconfig.json e colocar seu arquivo tsd.d.ts raiz como o primeiro arquivo.

Você também pode estar interessado em ler isso, cobrindo tsd e digitações https://angularclass.com/the-state-of-typescript-packages/

@joewood obrigado pela informação, a última vez que examinei o texto datilografado foi nos dias de arquivos individuais .d.ts . excelente artigo

@chanon @danpantry É um tanto lamentável que import foo = require('foo') (com foo sob node_modules) não funcione quando o package.json de foo não tem uma tipagem.

@wmono bem, já que talvez a sintaxe do TypeScript 0.80 ou talvez anterior import foo = require('foo') fosse apenas para importar módulos com tipagens. Se não tivesse digitação, você usaria var foo = require('foo') . Então eu diria que é do jeito que é.

@chanon me desculpe; erro do usuário. Parecia que o webpack estava lutando com o "bare" require mas o problema estava em outro lugar.

Desculpe alguém pode esclarecer porque
var foo = require('foo');
Funciona para um node_module padrão sem tipagens, mas
import foo from 'foo';
não? Isso foi apenas arbitrariamente definido? Não vejo por que o último _não deveria_ funcionar - não me importo se a biblioteca JS externa tem tipagens ou não.

Desculpe alguém pode esclarecer porque
var foo = require('foo');
Funciona para um node_module padrão sem tipagens, mas
importar foo de 'foo';
não? Isso foi apenas arbitrariamente definido? Não vejo por que o último não deveria funcionar - não me importo se a biblioteca JS externa tem tipagens ou não.

@harangue porque var require era uma das sintaxes de módulo concorrentes (esta sendo commonjs e outras na lista incluem amd ) que era suportada _fora do sistema de verificação de tipo_. Se alguém quiser usar o sistema de tipos, deve-se fazer import require . Com o ES6 pegando o :hammer: e dizendo que uma sintaxe (:ring:) para governá-los todos ... faz sentido ter essa sintaxe de módulo suportada pelo sistema de verificação de tipos fora da caixa :rose:

@basarat Obrigado pelo esclarecimento. Os ícones também foram úteis. ;) Ainda não tenho certeza porque a sintaxe ES6 exige verificação de tipo. O que impede o compilador de dizer - "oh, não consegui encontrar nenhum dado de tipo para esse módulo, mas vou importá-lo de qualquer maneira". Quais efeitos colaterais esse comportamento (bastante intuitivo, IMO) incorreria?

Isso é confuso para aqueles (como eu) que vêm do ES6 para o TypeScript. Eu esperaria que a sintaxe de importação do módulo ES6 se comportasse da mesma maneira no TypeScript, mas infelizmente não funciona para a maioria dos pacotes npm ...

mas infelizmente não funciona para a maioria dos pacotes npm ...

@teohhanhui estou confuso. Você pode dar um exemplo concreto do que você está tentando alcançar e qual código você tentou alcançar isso. Isso é só para que eu possa te ajudar :rose:

import koa from 'koa';

Cannot find module 'koa'. (2307) quando target é es6

koa está (claro) em node_modules

No entanto, koa não publica tipagens Typescript com seu projeto. Isso é apenas para pacotes que publicam um .d.ts com seu projeto e o listam em seu package.json. Como o koa não faz isso, você desejará instalar adicionalmente essas definições de tipo de Definitivamente tipado.

Isso parece uma decisão ruim, pois seria de esperar que a instrução import funcionasse como nos módulos ES6 simples. (Sim, eu sei, a maioria dos pacotes npm são módulos CommonJS, mas apoiá-los aqui ainda seria a coisa sensata a fazer.)

Sou novo no TypeScript, então provavelmente tenho um entendimento errado, mas as definições de tipo não são opcionais? Por que não posso importar o pacote sem a definição de tipo? Não quero ser forçado a procurar/criar definições de tipo.

Mudar para a sintaxe de importação do módulo TS legado não é uma opção porque não é permitido ao usar o destino es6 .

Sou novo no TypeScript, então provavelmente tenho um entendimento errado, mas as definições de tipo não são opcionais?

Isso é incorreto. As definições de tipo _no seu próprio código_ podem ser implícitas, o que significa que o compilador Typescript irá "descobrir". Você nunca passará uma biblioteca de terceiros pelo compilador Typescript, portanto, o compilador nunca saberá quais são esses tipos. Se você planeja usar código de terceiros, você realmente deve aprender a usar o Definitivamente Typed e a ferramenta tsd .

E essa resposta do @basarat?

http://stackoverflow.com/a/27434010/1529493

Por que os módulos não TypeScript sem definições de tipo não podem ser importados como tal?

Eles podem: const koa = require(‘koa’)

Em 21 de janeiro de 2016, às 14:47, Teoh Han Hui [email protected] escreveu:

Por que módulos sem definições de tipo não podem ser importados como tal?


Responda a este e-mail diretamente ou visualize-o no GitHub https://github.com/Microsoft/TypeScript/issues/247#issuecomment -173574234.

@bgrieder Estou me referindo à sintaxe de importação do ES6.

(ou seja, você está usando commonjs), se não, use a resposta declare var da Basarat

Em 21 de janeiro de 2016, às 14h48, Bruno Grieder bruno. [email protected] escreveu:

Eles podem: const koa = require(‘koa’)

Em 21 de janeiro de 2016, às 14:47, Teoh Han Hui < [email protected] [email protected] > escreveu:

Por que módulos sem definições de tipo não podem ser importados como tal?


Responda a este e-mail diretamente ou visualize-o no GitHub https://github.com/Microsoft/TypeScript/issues/247#issuecomment -173574234.

Eu acho que o ponto a ser feito é que um dos objetivos do TypeScript é que JS válido deve ser TS válido. Para a sintaxe do módulo ES6, o TS deve compilar com ou sem a presença de declarações de tipo. Sem declarações de tipo, uma instrução import deve apenas resolver para any .

Eu concordo totalmente com isso.

@Joe Wood 👍

Em 21 de janeiro de 2016, às 14:52, Joe Wood [email protected] escreveu:

Eu acho que o ponto a ser feito é que um dos objetivos do TypeScript é que JS válido deve ser TS válido. Para a sintaxe do módulo ES6, o TS deve compilar com ou sem a presença de declarações de tipo. Sem declarações de tipo, uma instrução de importação deve resolver apenas para qualquer.

Eu concordo totalmente com isso.


Responda a este e-mail diretamente ou visualize-o no GitHub https://github.com/Microsoft/TypeScript/issues/247#issuecomment -173575301.

FWIW esse comportamento (esperando que todas as bibliotecas de terceiros sejam digitadas com antecedência) é o que está me fazendo usar o Flow over TypeScript. Embora o TypeScript tenha suporte a IDE, esperar que tudo seja digitado com antecedência não é realmente razoável, especialmente quando há muitas bibliotecas por aí que:

  • Não estão em Definitivamente Typed
  • Não tem uma pasta ./typings
  • Eu não tenho tempo para digitar isso sozinho

Prefiro não ter que lutar contra algo que deveria estar ajudando meu desenvolvimento.

@danpantry , por que não apenas declarar seu ponto de entrada lib como qualquer, e o compilador ficará satisfeito com isso:

declare var $: any;

Essa é uma solução alternativa. Mas acho que seria uma boa ideia o TypeScript respeitar o código do módulo ES6 e fazer fallback normalmente. Não consigo ver uma boa razão pela qual uma instrução de importação não possa retornar para any em vez de relatar um erro se o módulo de nível superior não for digitado.

Prefiro que o compilador falhe cedo e ruidosamente (o comportamento atual), em vez de permitir que problemas de tempo de execução apareçam despercebidos. Eu preferiria explicitamente ter uma linha declare var foo: any para indicar "isso não é seguro e eu sei o que estou fazendo".

Por que não apenas permitir a sintaxe de importação do ES6 quando nenhuma digitação estiver disponível e emitir um simples aviso do compilador de que a importação foi resolvida para any , em vez de um erro de « prevenção de emissão » ?

Em 21 de janeiro de 2016, às 18:42, S. Chris Colbert [email protected] escreveu:

Prefiro que o compilador falhe cedo e ruidosamente (o comportamento atual), em vez de permitir que problemas de tempo de execução apareçam despercebidos. Eu preferiria ter explicitamente uma declaração var foo: qualquer linha para indicar "isso não é seguro e eu sei o que estou fazendo".


Responda a este e-mail diretamente ou visualize-o no GitHub https://github.com/Microsoft/TypeScript/issues/247#issuecomment -173649845.

De qualquer forma, o compilador atualmente afirma que não consegue encontrar o módulo, quando na verdade está apenas se recusando a importar o módulo sem definição de tipo. Isso não é realmente útil, é?

^^^ Isso mil vezes. Não havia nenhuma indicação de que eu estava fazendo algo errado quando me deparei com esse problema. Demorou um pouco de pesquisa no Google para finalmente descobrir o que estava acontecendo (aliás, acho que esse problema é um dos únicos lugares encontrados que o documenta). É tão desnecessário. E com o Angular 2 trazendo o TypeScript mais para o mainstream, só posso imaginar quantas perguntas do Stack Overflow virão desse comportamento.

Concordo muito com a má descrição do tratamento de erros e apenas faça a importação como qualquer outra!

@sccolbert Concordo que deve haver uma notificação, mas não tenho certeza se deve ser uma falha - um aviso, talvez

Concordo com @mhegazy e @sccolbert.

Eu prefiro que nossos scripts de compilação de produção (ou seja, servidor CI) reclamem em voz alta se algo estiver errado.

Oi pessoal,
Esse comportamento só me deixa louco. Os arquivos de definição não estão atualizados ou não estão registrados em package.json .
No final TypeScript produz JavaScript , então, até todos nós irmos para esta linguagem, por favor, seja gentil com o resto do mundo que fornece bibliotecas para a língua materna em qualquer outra linguagem transpilada, como a sua .
Eu realmente quero saber se TypeScript quer ficar (eu diria "integrar", pois parece que ainda não está lá) no ecossistema JavaScript ou quer viver uma vida separada, como a segunda opção me fará ir para outra coisa.
Para conseguir isso, um switch no arquivo .tsconfig fará, para isso podemos dizer que queremos importações estritas ou não.
Quanto à reclamação alta do CI, existem estruturas de teste para isso em JavaScript . De qualquer forma, você não terá verificação de tipo em tempo de execução, a verificação de importação ruim é a questão menos importante a ter.
Tudo de bom.

@devel-pa, os erros servem para informar que o compilador não tem ideia de qual é a sua importação. qualquer uso posterior da importação não pode ser verificado.

Desligar os erros não resolve nenhum problema. ele apenas empurra esses "desconhecidos" silenciosamente por todo o seu sistema. sem informações de tipo, o compilador não pode avisá-lo sobre o que é seguro e o que não é. e esse é o objetivo do TypeScript :)

Quanto ao JS gerado. nenhum dos erros do tipo TS impede que sua saída seja gerada. se você não se importa com os erros de tipo, apenas ignore todos eles. o compilador ainda gera seus arquivos .js correspondentes.

A solução para definições ausentes é declará-las. você não precisa ter a forma completa do módulo declarada, mas apenas o nome. Isso permite que o compilador saiba que existe um módulo "myLibrary", ele pode avisá-lo sobre erros de digitação nos nomes dos módulos e, mais importante, nenhum outro módulo ficará desmarcado.

declare module "myLibrary" {
    var a: any;
    export = a;
}

conforme descrito em #6615, o TypeScript deve oferecer suporte a uma forma mais curta disso em breve.

Eu acho que o problema é a dor que isso causa para projetos de integração. Eu acho que esse problema é análogo ao implícito any . No momento, essas importações são essencialmente void implícitas . Claro, os erros podem ser ignorados, mas isso causa muito barulho e vai contra a filosofia de tipagem gradual e JS válido é TS válido.

Eu posso entender a confusão aqui para pessoas novas no TS. Se eles usaram ativamente a sintaxe do módulo ES6 em JS, por que não funciona apenas no TS? O que há de especial em import from sobre var x = require - que _é_ tratado como um qualquer implícito. Originalmente import era uma palavra-chave específica do TS, então isso implicava que o desenvolvedor queria que o módulo fosse tratado como um módulo tipado. Agora que não é exclusivo do TS, não acho que essa suposição possa ser feita.

implícito-qualquer erro está em declarações de variável sem um tipo. mas usar uma variável não declarada ainda é um erro hoje. Para jquery, você ainda precisa de declare var $; em algum lugar para o compilador saber que você realmente queria ter uma variável global chamada $ e não apenas digitá-la incorretamente. é mais ou menos o mesmo para módulos, o compilador precisa saber que existe um módulo chamado "myLibrary" e que não é um nome errado. então basta adicionar uma declaração para ele.

De qualquer forma, #6615 deve suportar a adição declare module "*"; para corresponder a todos os módulos em seu sistema, embora eu ache que, se você fizer isso, não receberá nenhuma ajuda de suas ferramentas e estará se preparando para um doloroso transição mais tarde, quando você decidir removê-lo.

@mhegazy eu entendo seu raciocínio, mas eu realmente tenho um problema com esse raciocínio

Basicamente, você está nos dizendo para projetar uma definição de módulo "espaço reservado" e o problema desaparecerá.
Esse risco é que depois de um tempo, em um projeto de tamanho razoável, essas definições de "espaço reservado" podem simplesmente aparecer e serem enterradas em algum diretório de digitação. Não tendo mais avisos, todos simplesmente os esquecerão e, quando surgir um problema, passar por cada definição de módulo para ver qual é um espaço reservado, será uma dor.

A situação é ainda pior com módulos tipados (aqueles com a entrada typings em package.json) que supomos estar devidamente tipados, podem estar usando esses espaços reservados internamente.

Eu entendo que esses espaços reservados não podem ser evitados, mas eu preferiria que, pelo menos, eles não fossem incentivados.
O que deve ser defendido é que, por padrão, a importação resolva para any e que o compilador emita um aviso a cada compilação. Então, pelo menos, olhando os logs do compilador/CI, sabemos que algo é potencialmente suspeito e precisa ser melhorado.

(como um lado não, como indicado na página inicial do typescriptlang.org, o Typescript é um 'superconjunto' de Javascript, e IMHO qualquer sintaxe ES6 válida deve ser engolida como está)

Soluções alternativas e esconder o lixo debaixo do tapete são para mim o pior que pode acontecer (além do ES6 super).
Estou trabalhando com libs JS o tempo todo, e geralmente com as últimas versões como parte do meu trabalho e codificação extra em casa. 90% não são digitados ou possuem defs antigos, 9% não são muito bem digitados (pois o compilador não sabe fazer um def para todos os arquivos). Nenhum dos meus tem definições muito boas, pelo mesmo motivo anterior e pelo motivo de meu alvo ser JS, acho que não preciso me importar com o idioma original.
Além disso, eu vi a razão pela qual existem libs 'desconhecidas'. Não, de jeito nenhum, se os desenvolvedores não sabem e entendem quais libs são usadas, por que se preocupar com elas, eu sei por que estou usando coisas e por que estou adicionando à pilha. Avisos e testes (caso exista) são suficientes para isso.
Pls, JavaScript primeiro, este é o alvo e o ecossistema. O TS é apenas um acessório para melhor codificação e verificação de tipos em tempo de compilação, mas apenas para o que estamos construindo. O resto não é assunto de datilografia.
Quero mencionar que fui contra o nmps peerDependencies também, quem escolheu fui eu, não o software. Programação imperativa, querida.

que tal importar módulos do diretório JSPM em vez de node_modules?

edit: encontrei um ticket existente -> https://github.com/Microsoft/TypeScript/issues/6012

Acabei de encontrar um problema com a resolução do módulo Node, ao usar o SystemJS para carregar um diretório:

Aparentemente, enquanto o Node (e, portanto, o TypeScript) entende que o caminho é na verdade um diretório e, portanto, carrega index.ts , o SystemJS não faz isso, o que significa que o código TS válido não será carregado no navegador.

Isso também vale para módulos de nó que possuem um ponto de entrada index.ts/js ou até mesmo usam a propriedade package.json main . Isso é um pouco mais fácil de trabalhar, porque é fácil (embora repetitivo) adicionar uma configuração de pacote ao SystemJS. Isso não é tão fácil quando se trabalha com diretórios arbitrários.

Qual é a solução adequada para isso?

A resolução automática do módulo JSPM não é suportada atualmente. isso é rastreado por https://github.com/Microsoft/TypeScript/issues/6012.

A recomendação é usar o suporte à resolução do módulo de mapeamento de caminho, consulte https://github.com/Microsoft/TypeScript-Handbook/blob/release-2.0/pages/Module%20Resolution.md#path -mapping

As instruções acima são um começo, mas algumas pessoas podem precisar fazer algo adicional... Você pode ter que adicionar
<Folder Include="node_modules" />
para .njsproj

Mais informações

Eu estava construindo com gulp e tinha TypeScriptCompileBlocked em .nsproj. Para corrigir problemas na depuração de pontos de interrupção no VS 15 Preview 5 (eu estava recebendo o erro "frame not in module") e problemas que estava tendo com o intellisense, tive que adicionar para .njsproj . Esse diretório já estava lá quando importei o projeto, mas foi definido como git-ignore. Essa é a minha teoria sobre por que o Visual Studio o ignorou (talvez deva ter uma exceção automática para node_modules?)

Além do funcionamento da depuração e do intellisense, também parei de ver erros do intellisense além dos mesmos erros exatos que vi do gulp enquanto ele era construído, o que é esperado.

Esta página foi útil?
0 / 5 - 0 avaliações