基于laya air游戏开发实习日记之ts基础篇(二)

文章介绍了如何从JavaScript项目过渡到TypeScript,包括设置目录结构、配置tsconfig.json文件、处理JavaScript代码、启用严格检查以及解决转换过程中的错误。转换的关键步骤包括将.js文件重命名,处理模块导入导出,添加类型声明,并逐步消除错误。
摘要由CSDN通过智能技术生成
  • 从JavaScript到Typescript
  1. 设置目录

如果你在写纯JavaScript,你大概想要运行js文件,这些文件在src,lib或dist中都可以找到,运行起来的效果都是一样的

若如此,那么你写的纯JavaScript文件将做为TypeScript的输入,你将要运行的是TypeScript的输出。 在从JS到TS的转换过程中,我们会分离输入文件以防TypeScript覆盖它们。 你也可以指定输出目录。

你可能还需要对JavaScript做一些中间处理,比如合并或经过Babel再次编译。 在这种情况下,你应该已经有了如下的目录结构。

那么现在,我们假设你已经设置了这样的目录结构:

projectRoot

├── src

│   ├── file1.js

│   └── file2.js

├── built

└── tsconfig.json

如果你在src目录外还有tests文件夹,那么在src里可以有一个tsconfig.json文件,在tests里还可以有一个。

  • 书写配置文件

TypeScript使用tsconfig.json文件管理工程配置,例如你想包含哪些文件和进行哪些检查。 让我们先创建一个简单的工程配置文件:

{

    "compilerOptions": {

        "outDir": "./built",

        "allowJs": true,

        "target": "es5"

    },

    "include": [

        "./src/**/*"

    ]}

这里我为TypeScript设置了一些东西:

读取所有可识别的src目录下的文件(通过include)。

接受JavaScript做为输入(通过allowJs)。

生成的所有文件放在built目录下(通过outDir)。

将JavaScript代码降级到低版本比如ECMAScript 5(通过target)。

现在,如果你在工程根目录下运行tsc,就可以在built目录下看到生成的文件。 built下的文件应该与src下的文件相同。 现在你的工程里的TypeScript已经可以工作了。

  • 早期收益

现在你已经可以看到TypeScript带来的好处,它能帮助我们理解当前工程。 如果你打开像VS Code或Visual Studio这样的编译器,你就能使用像自动补全这样的工具。 你还可以配置如下的选项来帮助查找BUG:

noImplicitReturns 会防止你忘记在函数末尾返回值。

noFallthroughCasesInSwitch 会防止在switch代码块里的两个case之间忘记添加break语句。

TypeScript还能发现那些执行不到的代码和标签,你可以通过设置allowUnreachableCode和allowUnusedLabels选项来禁用。

  • 转换到TypeScript文件

到目前为止,你已经做好了使用TypeScript文件的准备。 第一步,将.js文件重命名为.ts文件。 如果你使用了JSX,则重命名为.tsx文件。

第一步达成? 太棒了! 你已经成功地将一个文件从JavaScript转换成了TypeScript!

当然了,你可能感觉哪里不对劲儿。 如果你在支持TypeScript的编辑器(或运行tsc --pretty)里打开了那个文件,你可能会看到有些行上有红色的波浪线。 你可以把它们当做在Microsoft Word里看到的红色波浪线一样。 但是TypeScript仍然会编译你的代码,就好比Word还是允许你打印你的文档一样。

如果对你来说这种行为太随便了,你可以让它变得严格些。 如果,你不想在发生错误的时候,TypeScript还会被编译成JavaScript,你可以使用noEmitOnError选项。 从某种意义上来讲,TypeScript具有一个调整它的严格性的刻度盘,你可以将指针拔动到你想要的位置。

如果你计划使用可用的高度严格的设置,最好现在就启用它们(查看启用严格检查)。 比如,如果你不想让TypeScript将没有明确指定的类型默默地推断为any类型,可以在修改文件之前启用noImplicitAny。 你可能会觉得这有些过度严格,但是长期收益很快就能显现出来。

  • 去除错误

我们提到过,若不出所料,在转换后将会看到错误信息。 重要的是我们要逐一的查看它们并决定如何处理。 通常这些都是真正的BUG,但有时必须要告诉TypeScript你要做的是什么。

  • 由模块导入

首先你可能会看到一些类似Cannot find name 'require'.和Cannot find name 'define'.的错误。 遇到这种情况说明你在使用模块。 你仅需要告诉TypeScript它们是存在的:

// For Node/CommonJS

declare function require(path: string): any;

// For RequireJS/AMD

declare function define(...args: any[]): any;

最好是避免使用这些调用而改用TypeScript的导入语法。

首先,你要使用TypeScript的module标记来启用一些模块系统。 可用的选项有commonjs,amd,system,and umd。

如果代码里存在下面的Node/CommonJS代码:

var foo = require("foo");

foo.doStuff();

或者下面的RequireJS/AMD代码:

define(["foo"], function(foo) {

    foo.doStuff();

})

那么可以写做下面的TypeScript代码:

import foo = require("foo");

foo.doStuff();

  • 获取声明文件

如果你开始做转换到TypeScript导入,你可能会遇到Cannot find module 'foo'.这样的错误。 问题出在没有声明文件来描述你的代码库。 幸运的是这非常简单。 如果TypeScript报怨像是没有lodash包,那你只需这样做

npm install -S @types/lodash

如果你没有使用commonjs模块模块选项,那么就需要将moduleResolution选项设置为node。

之后,你应该就可以导入lodash了,并且会获得精确的自动补全功能。

八、由模块导出

通常来讲,由模块导出涉及添加属性到exports或module.exports。 TypeScript允许你使用顶级的导出语句。 比如,你要导出下面的函数:

module.exports.feedPets = function(pets) {

    // ...

}

那么你可以这样写:

export function feedPets(pets) {

    // ...

}

有时你会完全重写导出对象。 这是一个常见模式,这会将模块变为可立即调用的模块:

var express = require("express");

var app = express();

之前你可以是这样写的:

function foo() {

    // ...

}

module.exports = foo;

在TypeScript里,你可以使用export =来代替。

function foo() {

    // ...

}

export = foo;

  • 过多或过少的参数

有时你会发现你在调用一个具有过多或过少参数的函数。 通常,这是一个BUG,但在某些情况下,你可以声明一个使用arguments对象的函数而不需要写出所有参数:

function myCoolFunction() {

    if (arguments.length == 2 && !Array.isArray(arguments[1])) {

        var f = arguments[0];

        var arr = arguments[1];

        // ...

    }

    // ...

}

myCoolFunction(function(x) { console.log(x) }, [1, 2, 3, 4]);

myCoolFunction(function(x) { console.log(x) }, 1, 2, 3, 4);

这种情况下,我们需要利用TypeScript的函数重载来告诉调用者myCoolFunction函数的调用方式。

function myCoolFunction(f: (x: number) => void, nums: number[]): void;

function myCoolFunction(f: (x: number) => void, ...nums: number[]): void;

function myCoolFunction() {

    if (arguments.length == 2 && !Array.isArray(arguments[1])) {

        var f = arguments[0];

        var arr = arguments[1];

        // ...

    }

    // ...

}

我们为myCoolFunction函数添加了两个重载签名。 第一个检查myCoolFunction函数是否接收一个函数(它又接收一个number参数)和一个number数组。 第二个同样是接收了一个函数,并且使用剩余参数(...nums)来表示之后的其它所有参数必须是number类型。

  • 连续添加属性

有些人可能会因为代码美观性而喜欢先创建一个对象然后立即添加属性:

var options = {};

options.color = "red";

options.volume = 11;

TypeScript会提示你不能给color和volumn赋值,因为先前指定options的类型为{}并不带有任何属性。 如果你将声明变成对象字面量的形式将不会产生错误:

let options = {

    color: "red",

    volume: 11

};

你还可以定义options的类型并且添加类型断言到对象字面量上。

interface Options { color: string; volume: number }

let options = {} as Options;

options.color = "red";

options.volume = 11;

或者,你可以将options指定成any类型,这是最简单的,但也是获益最少的。

any,Object,和{}

你可能会试图使用Object或{}来表示一个值可以具有任意属性,因为Object是最通用的类型。 然而在这种情况下any是真正想要使用的类型,因为它是最灵活的类型。

比如,有一个Object类型的东西,你将不能够在其上调用toLowerCase()。

越普通意味着更少的利用类型,但是any比较特殊,它是最普通的类型但是允许你在上面做任何事情。 也就是说你可以在上面调用,构造它,访问它的属性等等。 记住,当你使用any时,你会失去大多数TypeScript提供的错误检查和编译器支持。

如果你还是决定使用Object和{},你应该选择{}。 虽说它们基本一样,但是从技术角度上来讲{}在一些深奥的情况里比Object更普通。

  • 严格的null和undefined检查

默认地,TypeScript把null和undefined当做属于任何类型。 这就是说,声明为number类型的值可以为null和undefined。 因为在JavaScript和TypeScript里,null和undefined经常会导致BUG的产生,所以TypeScript包含了strictNullChecks选项来帮助我们减少对这种情况的担忧。

当启用了strictNullChecks,null和undefined获得了它们自己各自的类型null和undefined。 当任何值可能为null,你可以使用联合类型。 比如,某值可能为number或null,你可以声明它的类型为number | null。

假设有一个值TypeScript认为可以为null或undefined,但是你更清楚它的类型,你可以使用!后缀。

declare var foo: string[] | null;

foo.length;  // error - 'foo' is possibly 'null'

foo!.length; // okay - 'foo!' just has type 'string[]'

要当心,当你使用strictNullChecks,你的依赖也需要相应地启用strictNullChecks。

  • 学习心得体会

在本次学习中,对JavaScript到typescript的过渡有了一个比较明确的理解,ts是一个可以调整对代码的严格程度的语言,这使得他的兼容性更加的灵活,编译起来更轻松;另外一个重要的点就是导入功能,ts支持多种导入导出写法,如下:

import foo = require("foo");

foo.doStuff();

export function feedPets(pets) {

    // ...

}

var express = require("express");

var app = express();

之前你可以是这样写的:

function foo() {

    // ...

}

module.exports = foo;

在TypeScript里,你可以使用export =来代替。

function foo() {

    // ...

}

export = foo;

接下来学习ts具体的几个知识点,再做一个功能,就开始学习laya引擎

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值