Heim  >  Artikel  >  Web-Frontend  >  TypeScrip-Umgestaltungsprobleme und -lösungen

TypeScrip-Umgestaltungsprobleme und -lösungen

不言
不言Original
2018-07-25 10:08:472730Durchsuche

Der Inhalt, der in diesem Artikel mit Ihnen geteilt wird, befasst sich mit TypeScript-Transformationsproblemen und -lösungen. Als Nächstes werfen wir einen Blick auf die spezifischen Inhalte, in der Hoffnung, allen zu helfen.

Übersicht

Da es sich bei diesem Transformationsprojekt um ein über NPM veröffentlichtes Basisdienstpaket handelt, besteht das Ziel dieser Transformation mithilfe von TypeScript darin, den Bucket der Babel-Familie zu entfernen und die Paketgröße zu reduzieren und fügen Sie starke Typbeschränkungen hinzu, um mögliche Probleme in der zukünftigen Entwicklung zu vermeiden.

Diese Transformation verwendet TypeScript v2.9.2 und Webpack v4.16.0 zum Packen und Kompilieren. Das Entwicklungstool verwendet VSCode und das chinesische Sprachpaket. Das erwartete Ziel besteht darin, TypeScript-Code über den Loader direkt in ES5-Code zu kompilieren.

Einige der in diesem Artikel behandelten Probleme beziehen sich auf die Konfiguration und Verwendung von TypeScript, andere auf die Konfiguration von VSCode selbst.

Aufzeichnung und Analyse von Transformationsproblemen

VSCode-bezogen

Fehler „relevantes Modul konnte nicht gefunden werden“

Wenn wir im Projekt webpack.alias verwenden, werden wir möglicherweise aufgefordert, das Modul nicht zu finden.

Der spezifische Fehler lautet wie folgt:

终端编译报错:TS2307: Cannot find module '_utils/index'.
编辑器报错:[ts]找不到模块“_utils/index”。

Dies wird dadurch verursacht, dass der Editor die entsprechenden Alias-Informationen nicht lesen kann.

An dieser Stelle müssen wir prüfen, ob das entsprechende Modul vorhanden ist. Wenn bestätigt wird, dass das Modul vorhanden ist und während der Terminalkompilierung kein Fehler gemeldet wird, sondern nur ein Fehler vom Editor, liegt das daran, dass der Editor die Webpack-Konfiguration nicht lesen kann und wir zusätzliche Konfiguration hinzufügen müssen.

Lösung: Zusätzlich zur Konfiguration von webpack.alias müssen Sie auch das entsprechende tsconfig.json konfigurieren. Die spezifische Konfiguration lautet wie folgt:

"compilerOptions": {
    "baseUrl": ".",
    "paths": {
        "_util/*": [
            "src/core/utils/*"
        ]
    }
}

Hinweis: Wenn tsconfig.json wird später konfiguriert. Wenn weiterhin ein Fehler auftritt, müssen Sie VSCode neu starten. Es wird spekuliert, dass VSCode nur relevante Konfigurationsinformationen liest, wenn das Projekt geladen wird. Das Gleiche gilt für jsconfig.json in JavaScript-Projekten.

TypeScript-bezogen

Fehler bei der Zuweisung von Objektattributen

In JavaScript deklarieren wir häufig ein leeres Objekt und Weisen Sie diesem Attribut dann einen Wert zu. Wenn dieser Vorgang jedoch in TypeScript ausgeführt wird, tritt ein Fehler auf:

let a = {};

a.b = 1;
// 终端编译报错:TS2339: Property 'b' does not exist on type '{}'.
// 编辑器报错:[ts] 类型“{}”上不存在属性“b”。

Dies liegt daran, dass TypeScript das Hinzufügen nicht deklarierter Attribute nicht zulässt.

Daher haben wir zwei Möglichkeiten, diesen Fehler zu beheben:

  1. Attributdefinitionen zum Objekt hinzufügen (empfohlen). Die spezifische Methode ist: let a = {b: void 0};。 Diese Methode kann das aktuelle Problem grundsätzlich lösen und auch das Problem der zufälligen Zuweisung von Objekten vermeiden.

  2. Fügen Sie dem Objekt a ein beliebiges Attribut hinzu (Notfall). Die spezifische Methode ist: let a: any = {};. Diese Methode ermöglicht es TypeScript, dieses Objekt während der Typprüfung zu ignorieren, sodass während der Kompilierung kein Fehler gemeldet wird. Diese Methode eignet sich für große Mengen alter Codetransformationen.

Fehler bei der Zuweisung von Fensterobjektattributen gemeldet

Ähnlich wie in der vorherigen Situation, wenn wir einem Objekt ein nicht vorhandenes Attribut zuweisen, eine Bearbeitung wird angezeigt Der Compiler und der Compiler haben einen Fehler gemeldet:

window.a = 1;
// 终端编译报错:TS2339: Property 'a' does not exist on type 'Window'.
// 编辑器报错:[ts] 类型“Window”上不存在属性“a”。

Dies liegt auch daran, dass TypeScript das Hinzufügen nicht deklarierter Attribute nicht zulässt.

Da wir keine Möglichkeit haben, den Wert des Windows-Attributs zu deklarieren (oder es sehr schwierig ist), müssen wir es wie folgt lösen:

  1. Wir Verwendung in Windows Fügen Sie eine Typkonvertierung hinzu, nämlich (window as any).a = 1;. Dadurch wird sichergestellt, dass es im Editor und beim Kompilieren zu keinen Fehlern kommt. Diese Methode wird jedoch nur für die Renovierung alter Projekte empfohlen. Wir sollten versuchen, das Hinzufügen von Attributen zum Fensterobjekt zu vermeiden. Der Zugriff auf die Daten sollte über einen globalen Datenmanager erfolgen.

Die neue Methode von ES2015 Object in der Prototypenkette meldet einen Fehler

Im Projekt werden einige neue ES2015-Methoden in der Prototypenkette von Object verwendet Bei hinzugefügten Methoden wie Object.assign und Object.values usw. schlägt die Kompilierung zu diesem Zeitpunkt fehl und VSCode gibt einen Fehler aus:

终端编译报错:TS2339: Property 'assign' does not exist on type 'ObjectConstructor'.
编辑器报错:[ts] 类型“ObjectConstructor”上不存在属性“assign”。

Dies liegt daran, dass tsconfig.json wir in ist ES5. TypeScript verfügt nicht über verwandte Polyfills, daher können wir die neuen Methoden in ES2015 nicht verwenden. target

Lösung: Sie können die entsprechenden Methoden im lodash-Tool-Set verwenden. Sie müssen

und lodash.assign während der Installation installieren. Und @types/lodash.assign ist ein CMD-Standardpaket und muss über lodash.assign eingeführt werden. import _assign = require('lodash.assing');

ES2015 neue Datenstruktur Map-Initialisierungsfehler

Wenn Sie beim Umwandeln von ES2015-Code in TypeScript-Code den neuen Map-Typ in ES2015 verwenden, wird ein Fehler gemeldet Kompilieren im Editor oder Terminal:

终端编译报错:TS2693: 'Map' only refers to a type, but is being used as a value here.
编辑器报错报错:[ts] “Map”仅表示类型,但在此处却作为值使用。
Dies liegt daran, dass TypeScript keine relevanten Datentypen bereitstellt und es kein entsprechendes Polyfill gibt.

Daher haben wir drei Ideen, um dieses Problem zu lösen:

  1. tsconfig.json配置中的target属性改为es6,即输出符合ES2015规范的代码。因为ES2015存在全局的Promise对象,因此编译和编辑器都不会报错。该方法优点为配置简单,无需改动代码,缺点为需要高级浏览器的支持或者Babel全家桶的支持。

  2. 舍弃Map类型,改用Object进行替代。这种改造比较费时费力,适用于工作量较小和不愿意引入其他文件的场景。

  3. 自行实现或者安装一个Map包。这种方法改造成本较小,缺点就是会引入额外的代码或者包,并且代码效率无法保证。例如ts-maptypescript-map,这两个包的查找效率都是o(n),低于原生类型的Map。因此推荐自己使用Object实现一个简单的Map,具体实现方式可以去网上找相关的Map原理分析与实践(大致原理为使用多个Object,存储不同类型元素时使用不同容器,避免类型转换问题)。

ES2015新增的Promise使用报错

将ES2015的代码改造成为TypeScript代码时,如果你使用了ES2015的新增的Promise类型,那在编辑器还是终端编译编译时都会报错:

终端编译报错: TS2693: 'Promise' only refers to a type, but is being used as a value here.
编辑器报错:[ts] “Promise”仅表示类型,但在此处却作为值使用。

这是由于TypeScript并没有提供Promise数据类型,也没有对应的polyfill。

因此,我们解决这个问题的思路仍然有三种:

  1. tsconfig.json配置文件配置中的target属性改为es6,即输出符合ES2015规范的代码。因为ES2015存在全局的Promise对象,因此编译和编辑器都不会报错。该方法优点为配置简单,无需改动代码,缺点为需要高级浏览器的支持或者Babel全家桶的支持。

  2. 引入一个Promise库,如bluebird等比较知名的Promise库。在安装bluebird时需要同时安装@types/bluebird声明文件。缺点就是引入的Promise库较大,而且如果你的库作为一个基础库时,可能会与其他的调用方的Promise库产生冲突。

  3. tsconfig.json配置文件中增加lib。此方法的原理是让TypeScript编译时引用外部的Promise对象,因此在编译时不会报错。此方式优点是不会引入任何其他代码,但是缺点是一定要保证在引用此库的前提下,一定存在Promise对象。具体配置如下:

    "compilerOptions": {
        "lib": ["es2015.promise"]
    }

SetTimeout使用报错

将ES2015代码改造成TypeScript代码时,如果使用了setTimeout和setInterval函数时,可能会出现无法找到该函数的报错:

终端编译报错:TS2304: Cannot find name 'setTimeout'.
编辑器报错:[ts] 找不到名称“setTimeout”。

这是由于编辑器和编译时不知道当前代码运行环境导致的。

因此,我们解决这个问题的思路有两种:

  1. tsconfig.json配置文件中增加lib。让TypeScript能够知道当前的代码容器。具体示例如下:

    "compilerOptions": {
        "lib": ["dom"]
    }
  2. 安装@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] 应为声明或语句。

这是由于两者的模块语法不一样导致的。

因此,我们解决这个问题只需要用下面这一种方法:

  1. 将上面的export from的语法稍加调整来适配TypeScript语法。具体改造如下:

    export {default as Session} from '_models/session'; //调整后不报错
    export * from '_models/read-item';// 之前不报错不需要调整

总结

在做项目TypeScript改造的过程中,遇到了不少大大小小的坑。很多问题在网上都没有解决方案或者没有说明白具体的解决步骤,因此希望通过这一篇文章来帮助大家在进行TypeScript迁移时避免在我踩过的坑上再浪费时间。

相关推荐:

关于TypeScript在node项目中的实践分析

Das obige ist der detaillierte Inhalt vonTypeScrip-Umgestaltungsprobleme und -lösungen. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn