Le contenu partagé avec vous dans cet article concerne les problèmes et les solutions de transformation TypeScript. Le contenu est très détaillé. Examinons ensuite le contenu spécifique, dans l'espoir d'aider tout le monde.
Étant donné que ce projet de transformation est un package de services de base publié via NPM, l'objectif de cette transformation utilisant TypeScript est de supprimer le bucket de la famille Babel, de réduire la taille du package , et ajoutez des contraintes de type fortes pour éviter d'éventuels problèmes lors du développement futur.
Cette transformation utilise TypeScript v2.9.2 et Webpack v4.16.0 pour le packaging et la compilation. L'outil de développement utilise VSCode et utilise le pack de langue chinoise. L'objectif attendu est de compiler directement du code TypeScript en code ES5 via le chargeur.
Certains des problèmes impliqués dans cet article sont liés à la configuration et à l'utilisation de TypeScript, et d'autres sont liés à la configuration de VSCode lui-même.
Dans le projet, si nous utilisons webpack.alias, nous pouvons être informés que le module est introuvable.
Les erreurs spécifiques sont les suivantes :
终端编译报错:TS2307: Cannot find module '_utils/index'. 编辑器报错:[ts]找不到模块“_utils/index”。
Cela est dû au fait que l'éditeur n'est pas en mesure de lire les informations d'alias correspondantes.
À ce stade, nous devons vérifier si le module correspondant existe. S'il est confirmé que le module existe et qu'aucune erreur n'est signalée lors de la compilation du terminal, mais que seule une erreur est signalée par l'éditeur, c'est parce que l'éditeur ne peut pas lire la configuration du webpack et que nous devons ajouter une configuration supplémentaire.
Solution : En plus de configurer webpack.alias, vous devez également configurer le tsconfig.json
correspondant. La configuration spécifique est la suivante :
"compilerOptions": { "baseUrl": ".", "paths": { "_util/*": [ "src/core/utils/*" ] } }
Remarque : Si <. est configur> Si vous obtenez toujours une erreur à l'avenir, vous devez redémarrer VSCode. On suppose que VSCode ne lit les informations de configuration pertinentes que lorsque le projet est chargé. Il en va de même pour tsconfig.json
dans les projets JavaScript. jsconfig.json
let a = {}; a.b = 1; // 终端编译报错:TS2339: Property 'b' does not exist on type '{}'. // 编辑器报错:[ts] 类型“{}”上不存在属性“b”。
Cette méthode peut résoudre fondamentalement le problème actuel et peut également éviter le problème des valeurs attribuées aux objetsà volonté. let a = {b: void 0};。
(urgence). La méthode spécifique est : a
. Cette méthode permet à TypeScript d'ignorer cet objet lors de la vérification du type, afin qu'aucune erreur ne soit signalée lors de la compilation. Cette méthode convient à de grandes quantités de transformations d’anciens codes. let a: any = {};
window.a = 1; // 终端编译报错:TS2339: Property 'a' does not exist on type 'Window'. // 编辑器报错:[ts] 类型“Window”上不存在属性“a”。
. Cela garantit qu'il n'y aura pas d'erreurs dans l'éditeur et lors de la compilation. Cependant, cette méthode n'est recommandée que pour la rénovation d'anciens projets. Nous devons essayer d'éviter d'ajouter des attributs à l'objet window. Les données doivent être accessibles via un gestionnaire de données global. (window as any).a = 1;
et Object.assign
, etc., la compilation échouera à ce moment-là et VSCode affichera une erreur : Object.values
终端编译报错:TS2339: Property 'assign' does not exist on type 'ObjectConstructor'. 编辑器报错:[ts] 类型“ObjectConstructor”上不存在属性“assign”。
que nous avons spécifié dans tsconfig.json
est ES5 et TypeScript n'a pas de polyfills associés, nous ne pouvons donc pas utiliser les nouvelles méthodes dans ES2015. target
et lodash.assign
lors de l'installation. Et @types/lodash.assign
est un package standard CMD et doit être introduit via lodash.assign
. import _assign = require('lodash.assing');
终端编译报错:TS2693: 'Map' only refers to a type, but is being used as a value here. 编辑器报错报错:[ts] “Map”仅表示类型,但在此处却作为值使用。
将tsconfig.json
配置中的target
属性改为es6
,即输出符合ES2015规范的代码。因为ES2015存在全局的Promise对象,因此编译和编辑器都不会报错。该方法优点为配置简单,无需改动代码,缺点为需要高级浏览器的支持或者Babel全家桶的支持。
舍弃Map类型,改用Object进行替代。这种改造比较费时费力,适用于工作量较小和不愿意引入其他文件的场景。
自行实现或者安装一个Map包。这种方法改造成本较小,缺点就是会引入额外的代码或者包,并且代码效率无法保证。例如ts-map
和typescript-map
,这两个包的查找效率都是o(n),低于原生类型的Map。因此推荐自己使用Object实现一个简单的Map,具体实现方式可以去网上找相关的Map原理分析与实践(大致原理为使用多个Object,存储不同类型元素时使用不同容器,避免类型转换问题)。
将ES2015的代码改造成为TypeScript代码时,如果你使用了ES2015的新增的Promise类型,那在编辑器还是终端编译编译时都会报错:
终端编译报错: TS2693: 'Promise' only refers to a type, but is being used as a value here. 编辑器报错:[ts] “Promise”仅表示类型,但在此处却作为值使用。
这是由于TypeScript并没有提供Promise数据类型,也没有对应的polyfill。
因此,我们解决这个问题的思路仍然有三种:
将tsconfig.json
配置文件配置中的target
属性改为es6
,即输出符合ES2015规范的代码。因为ES2015存在全局的Promise对象,因此编译和编辑器都不会报错。该方法优点为配置简单,无需改动代码,缺点为需要高级浏览器的支持或者Babel全家桶的支持。
引入一个Promise库,如bluebird等比较知名的Promise库。在安装bluebird时需要同时安装@types/bluebird声明文件。缺点就是引入的Promise库较大,而且如果你的库作为一个基础库时,可能会与其他的调用方的Promise库产生冲突。
在tsconfig.json
配置文件中增加lib。此方法的原理是让TypeScript编译时引用外部的Promise对象,因此在编译时不会报错。此方式优点是不会引入任何其他代码,但是缺点是一定要保证在引用此库的前提下,一定存在Promise对象。具体配置如下:
"compilerOptions": { "lib": ["es2015.promise"] }
将ES2015代码改造成TypeScript代码时,如果使用了setTimeout和setInterval函数时,可能会出现无法找到该函数的报错:
终端编译报错:TS2304: Cannot find name 'setTimeout'. 编辑器报错:[ts] 找不到名称“setTimeout”。
这是由于编辑器和编译时不知道当前代码运行环境导致的。
因此,我们解决这个问题的思路有两种:
在tsconfig.json
配置文件中增加lib。让TypeScript能够知道当前的代码容器。具体示例如下:
"compilerOptions": { "lib": ["dom"] }
安装@types/node
。该方法适用于node环境下或者采用webpack打包时可以引入node代码。该方法直接通过npm install @types/node
即可安装完成,解决报错问题。
在ES2015的代码中,我们可以通过@babel/plugin-proposal-export-default-from
插件来直接导出引入的文件,具体示例如下:
export Session from './session'; // 报错 export * from '_models/read-item'; // 不报错
而在TypeScript中,这种写法是会报错的:
终端编译报错:TS1128: Declaration or statement expected. 编辑器报错:[ts] 应为声明或语句。
这是由于两者的模块语法不一样导致的。
因此,我们解决这个问题只需要用下面这一种方法:
将上面的export from
的语法稍加调整来适配TypeScript语法。具体改造如下:
export {default as Session} from '_models/session'; //调整后不报错 export * from '_models/read-item';// 之前不报错不需要调整
在做项目TypeScript改造的过程中,遇到了不少大大小小的坑。很多问题在网上都没有解决方案或者没有说明白具体的解决步骤,因此希望通过这一篇文章来帮助大家在进行TypeScript迁移时避免在我踩过的坑上再浪费时间。
相关推荐:
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!