作为一个前端语言,Javascript 从最初只是用来写页面,到如今的移动终端、后端服务、神经网络等等,它变得几乎无处不在。如此广阔的应用领域,对语言的安全性、健壮性以及可维护性都有了更高的要求。尽管 ECMAScript 标准在近几年有了长足的进步,但是在类型检查方面依然毫无建树。在这种情况下 TypeScript 应运而生。
在 JavaScript 的开发过程中,相信经常会遇到以下这种场景:
以上情况归结底,是因为 JavaScript 是一门动态弱类型语言,对变量的类型非常宽容,而且不会在这些变量和它们的调用者间建立结构化的契约。如果你长期在没有类型约束的环境下开发,就会造成 “类型思维” 的缺失,养成不良的编程习惯,这也是做前端开发的短板之一,因此使用 TypeScript 对于前端开发者而言是迫切并且必要的。
使用 TypeScript 还能带来其他好处。比如,Visual Studio Code 具有强大的自动补全、导航和重构功能,这使得接口定义可以直接代替文档,同时也提高了开发效率,降低了维护成本。更重要的是,TypeScript 可以帮助团队重塑 “类型思维”,使前端开发者从代码的编写者蜕变为代码的设计者。
如果说 JavaScript 是一匹野马,那么 TypeScript 就是束缚这匹野马的缰绳。作为骑士的你,自然可以张开双臂,放飞自我,但如果不是技艺超群,恐怕会摔得很惨。然而如果抓住了缰绳,你即可闲庭信步,亦可策马扬鞭。这就是 TypeScript 的价值,它会让你在前端开发之路上走得更稳,走得更远。
什么是 TypeScript 呢?根据官方的定义,它是拥有类型系统的 JavaScript 的超集,可以编译成纯 JavaScript。在这里需要注意三点:
Ts 包含类型如下:
let arr: number[] = [1, 3]
let arr:Array<number> = [1,2]
5.元组: 无关键字,元组类型用来表示已知元素个数和类型的数组,每个元素的类型不必相同,但是对应位置的类型需要相同;
let x: [string, number];
x = ['Runoob', 1]; // 运行正常
x = [1, 'Runoob']; // 报错
console.log(x[0]); // 输出 Runoob
x.push(33)
console.log(x[2]) // 报错
// 注意x可以继续push多个字段,但是无法访问
6.枚举(enum): 枚举类型用于定义类型集合
数字枚举:默认情况下,第一个枚举值是 0,然后每个后续值依次递增 1, 但是,你可以通过特定的赋值来改变给任何枚举成员关联的数字,如下例子,我们从 3 开始依次递增
enum Color {
Red, // 0
Green, // 1
Blue // 2
};
let c: Color = Color.Blue;
console.log(c); // 输出 2
console.log(Color[0]) // 输出Red
enum Color1 {
Red = 3, // 3
Green, // 4
Blue // 5
}
7.void: 用于标识方法的返回值,表示没有返回值
8.null: 标识对象值缺失;
9.undefined: 用于初始化变量为一个未定义的值
10.never: 是其它类型(包括 null 和 undefined)的子类型,代表从不会出现的值
11.Object:object 表示非原始类型,也就是除 number,string,boolean,symbol,null 或 undefined 之外的类型。
12.any:任意值是 TypeScript 针对编程时类型不明确的变量使用的一种数据类型;(注意:不要轻易使用 any,使用 any 跟使用 javascript 效果一样了)
它常用于以下三种情况:
13.联合类型:可以通过管道 (|) 将变量设置多种类型,赋值时可以根据设置的类型来赋值
var val:string|number
val = 12
console.log("数字为 "+ val)
val = "Runoob"
console.log("字符串为 " + val)
// 包含两个number类型参数和返回值,不能直接return。必须return一个数字
function add(x: number, y: number): number {
return x + y;
}
// 可选参数, (这里没写返回值,利用了typeScript的类型推断能力)
function buildName(firstName: string, lastName?: string, a?:number) {
if (lastName)
return firstName + " " + lastName;
else
return firstName;
}
// 参数默认值
function buildName(firstName: string, lastName: string = 'default_name') {
return firstName + " " + lastName;
}
// 有一种情况,我们不知道要向函数传入多少个参数,这时候我们就可以使用剩余参数来定义,
// 剩余参数语法允许我们将一个不确定数量的参数作为一个数组传入
function buildName(firstName: string, ...restOfName: string[]) {
return firstName + " " + restOfName.join(" ");
}
let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");
接口是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的类去实现,然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法。
interface IPerson {
firstName:string,
lastName:string,
sayHi: ()=>string
}
const customer:IPerson = {
firstName:"Tom",
lastName:"Hanks",
sayHi: ():string =>{return "Hi there"}
}
接口可以通过继承来扩展自己,继承使用关键字 extends, 可以单继承和多继承
interface Person {
age:number
}
interface Musician extends Person, person1 {
instrument:string
}
TypeScript 是面向对象的 JavaScript,类描述了所创建的对象共同的属性和方法。
定义类的关键字为 class,后面紧跟类名,类可以包含以下几个模块(类的数据成员):
class Car {
// 字段
engine:string;
// 构造函数
constructor(engine:string) {
this.engine = engine
}
// 方法
disp():void {
console.log("发动机为 : "+this.engine)
}
}
const car = new Car('')
总体而言,TypeScript 是一个很好的工具,即使您没有使用过它,也可以将它纳入您的学习计划中。因为它能在你脑中播下 “类型思维” 的种子,而思维方式决定了编程习惯,编程习惯奠定了工程质量,工程质量划定了能力边界。在面对越来越复杂的前端场景,TypeScript 所提供的思维方式,能够让你在以后的开发中长期受益。
作者:京东物流 吴云阔
来源:京东云开发者社区