TypeScript
什么是 TypeScript?
TypeScript
是 JavaScript
的类型的超集,它可以编译成纯 JavaScript
。 编译出来的 JavaScript
可以运行在任何浏览器上。TypeScript
编译工具可以运行在任何服务器和任何系统上。TypeScript
是开源的。
为什么选择TypeScript
TypeScript 增加了代码的可读性和可维护性
-
类型系统实际上是最好的文档,大部分的函数看看类型的定义就可以知道如何使用了
-
可以在编译阶段就发现大部分错误,这总比在运行时候出错好
-
增强了编辑器和 IDE 的功能,包括代码补全、接口提示、跳转到定义、重构等
安装 TypeScript
npm install -g typescript
编译一个 TypeScript
文件 , TypeScript
编写的文件以 .ts
为后缀,用 TypeScript
编写 React
时,以 .tsx
为后缀。
tsc hello.ts 编译命令会声场hello.js文件
hello.ts:
function sayHello(person: string) { return 'Hello, ' + person; } let user = 'Tom'; console.log(sayHello(user));
生成的hello.js
function sayHello(person) { return 'Hello, ' + person; } var user = 'Tom'; console.log(sayHello(user));
TypeScript
中,使用 :
指定变量的类型,:
的前后有没有空格都可以。 person
参数类型为 string
TypeScript
编译的时候即使报错了,还是会生成编译结果,我们仍然可以使用这个编译之后的文件。
错误演示: person
参数类型为 string 传值为数组
function sayHello(person: string) { return 'Hello, ' + person; } let user = [0, 1, 2]; console.log(sayHello(user));
编辑器中会提示错误,编译的时候也会出错
index.ts(6,22): error TS2345: Argument of type 'number[]' is not assignable to parameter of type 'string'.
TypeScript中数据类型介绍
- 定义布尔类型
//ts声明布尔类型的变量let flag:boolean=true;
- ts中定义数值类型
let count:number=100
- ts中定义字符类型
let str:string='hello world'
- ts定义void类型:
void
表示没有任何返回值的函数: -
function print:void(params){ console.log(params); } //声明一个void类型的变量没有什么大用,因为你只能为它赋予undefined和null: let unusable: void = undefined;
- ts中定义undefined类型
let a:undefined=undefined
- ts中定义null
let b:null=null
undefined
和null
是所有类型的子类型。也就是说undefined
类型的变量,可以赋值给number
类型的变量:-
// 这样不会报错 let num: number = undefined; // 这样也不会报错 let u: undefined; let num: number = u;
- ts中定义any(任意类型:变量值可以为任意类型),如果是一个普通类型,在赋值过程中改变类型是不被允许的:
any
类型,则允许被赋值为任意类型。let anyData:any=''
-
//普通类型会报错 let myFavoriteNumber: string = 'seven'; myFavoriteNumber = 7; // index.ts(2,1): error TS2322: Type 'number' is not assignable to type 'string'. //any类型不会报错 let myFavoriteNumber: any = 'seven'; myFavoriteNumber = 7;
- 定义数组:
第一种:元素类型后面加一个[]
// 定义一个组成元素为数字的数组 let arr1:number[]=[1,2,3,4] //定义一个字符数组 let arr2:string[]=['jack','robin','pony'] // 定义一个对象数组 let arr3:object[]=[ {name:'jack',age:1967}, {name:'robin',age:1968}, {name:'pony',birthday:1974} ]
- 第二种:使用数组泛型,
Array<元素类型>
//定义一个组成元素为字符的数组 let arr1:Array<string>=['jack','robin','pony'] //定一个数字数组 let arr2:Array<number>=[1,2,3,4] //定义一个对象数组 let arr3:Array<object>=[ {name:'jack',age:1967}, {name:'robin',age:1968}, {name:'pony',birthday:1974} ]
- 对象的定义
方案1:
// 在对象名后面使用一个{}来进行对象属性值类型的约束 let obj:{name:string,age:number,isMarry:boolean}={ name:'zs', age:30, isMarry:false }
方案2:
定义了一个接口 Person
,接着定义了一个变量 p1,它的类型是
Person
。这样,我们就约束了 p1 的形状必须和接口
Person
一致。
定义的变量比接口少了一些属性是不允许的,多一些属性也是不允许的,赋值的时候,变量的形状必须和接口的形状保持一致。
// 使用接口定义属性值的类型 interface Person={ name:string; age:number; isMarry:boolean; } // 创建对象的时候引用该接口, 进行属性值类型的约束 let p1:Person={ name:'zs', age:30, isMarry:false }
函数的定义
函数有输入和输出,要在 TypeScript 中对其进行约束,需要把输入和输出都考虑到
加入了类型的约束,只要体现在参数和返回值上面
1. 函数声明的类型定义
function sum(a:number,b:number):string{ return '求和结果为:'+(a+b); }
输入多余的(或者少于要求的)参数,是不被允许的
2. 函数表达式定义
let mySum: (x: number, y: number) => number = function (x: number, y: number): number { return x + y; };
注意不要混淆了 TypeScript 中的 =>
和 ES6 中的 =>
。
在 TypeScript 的类型定义中,=>
用来表示函数的定义,左边是输入类型,需要用括号括起来,右边是输出类型。
interface SearchFunc { (source: string, subString: string): boolean; } let mySearch: SearchFunc; mySearch = function(source: string, subString: string) { return source.search(subString) !== -1; }
类(class)
// 类(class)相当于ES5中的构造函数 class Person{ // 声明静态属性 static version:string='V1.0.0'; //声明成员属性; 并进行数据类型的约束 name:string; age:number; sex:string; //构造函数,做一些初始化的事,比如给成员属性赋值 constructor(props){ //成员属性赋值 this.name=props.name; this.age=props.age; this.sex=props.sex; } //声明成员方法1 sayName(){ console.log('My name is '+this.name); } //声明成员方法2 dance(){ console.log('我会跳新疆舞'); } // 静态成员方法 static sayHi():string{ console.log('hello world!!!'); return 'hello world!!'; } } //创建实例:和js中一样 let p1=new Person({name:'zs',age:10,sex:'男'})
类的继承(extends)
//通过extends语法结构继承Person类的属性和方法 class Student extends Person{ //声明自己独有的成员属性; 并进行数据类型的约束 addr:string; constructor(props){ //必须在此处使用super()先调用父类的构造函数 super(props); //属性赋值 this.addr=props.addr } //添加自己独有的成员方法 hobby(){ console.log('爱生活,爱代码'); } } //创建实例对象 let s1=new Student({name:'ls',age:10,sex:'女',addr:'中国西安'});
类型别名
类型别名用来给一个类型起个新名字。
type Name = string; type NameResolver = () => string; type NameOrResolver = Name | NameResolver; function getName(n: NameOrResolver): Name { if (typeof n === 'string') { return n; } else { return n(); } }
字符串字面量类型
字符串字面量类型用来约束取值只能是某几个字符串中的一个。
type EventNames = 'click' | 'scroll' | 'mousemove'; function handleEvent(ele: Element, event: EventNames) { // do something } handleEvent(document.getElementById('hello'), 'scroll'); // 没问题 handleEvent(document.getElementById('world'), 'dbclick'); // 报错,event 不能为 'dbclick' // index.ts(7,47): error TS2345: Argument of type '"dbclick"' is not assignable to parameter of type 'EventNames'.
使用 type
定了一个字符串字面量类型 EventNames
,它只能取三种字符串中的一种。取其余的会报错
参考文章:TypeScript 入门教程 https://ts.xcatliu.com/
TypeScript 官方指南 https://www.tslang.cn/docs/handbook/basic-types.html