简介
TypeScript是JavaScript的超集(继承了JS的全部语法),TypeScript = Type + JavaScript
简单来说, 就是在JS的基础上,为JS添加了类型支持。
TS是微软开发的开源编程语言,可以在任何运行JS的地方运行。
let uname: string = 'tom';
let count: number = 10;
类型注解:指在变量、函数定义的时候,使用特定语法(:type)来指定其类型,并在代码中限制只能接收特定类型的值
- JS和TS的区别
但是浏览器不能直接使用TS,需要编译为JS运行。
安装TS编译器:
npm install -g typescript
编译ts:
tsc demo.ts
但是默认编译版本为es3(比较低),编译出的js文件使用的是过时的var:
//编译后的js文件
var uname = 'tom';
var count = 10;
console.log("uname:".concat(uname, " --- count:").concat(count));
可以通过参数 -target指定编译时的目标版本,如:es6、esnext等
//编译后的js文件
let uname = 'tom';
let count = 10;
console.log(`uname:${uname} --- count:${count}`);
实际上就是将类型参数去掉了
常见类型
TS中除了JS的数据类型之外,还提供了新的实用数据类型:
基础类型
- 基础类型
string、number、boolean、null/undefined、any、number[]/Array<number>
原则上不推荐any,这会让TypeScript失去类型保护的优势,等同于JavaScript
联合类型
- 如果数组中有number类型,string类型,可以使用联合类型指定
联合类型是指由多个类型组成的类型,可以是多个类型的其中任意一种。
写法:类型1 | 类型2
//建议使用(|)
let arr1: (number | string)[] = ['d','e','f',4,5,6];
let flag: (boolean | number) = true;
flag = 0;
flag = 1;
flag = false;
- 类型别名:相当于一种自定义类型,为任意类型起别名
使用场景:当同一个联合类型多次使用的时候,可以通过类型别名,简化该类型的书写
语法:
type customType = 指定类型
//多次使用
let arr3: (number | string)[] = ['a','b','c',1,2,3];
let arr4: (number | string)[] = ['d','e','f',4,5,6];
//指定类型
type numStrArr = (number | string)[];
let arr5:numStrArr = ['g','h','i',7,8,9];
console.log(`${arr3}\n${arr4}\n${arr5}`)
函数类型
函数类型实际上指的是:函数的参数及返回值的类型
//具名函数
function add(x: number,y: number): number{
return x + y;
}
//匿名函数
let add2 = function (x: number,y: number) : number{
return x + y;
}
//箭头函数
let add3 = (x: number,y: number) : number => {
return x + y;
}
//箭头函数
let add4: (x:number)=> number = (x) => {
return x + 1;
}
如果函数没有返回值,则是 : void
注意:与JS不同的是,TS中函数调用时的实际入参和定义时的形式入参必须保持个数一致
- 可选参数:TS中可以使用?实现可选参数的功能,可选参数只能出现在参数列表的最后
let getFullName = (firstName: string,lastName?: string):string => {
if (lastName){ //隐含的Boolean(),空字符串/null/undefined/0/NaN均为false
return firstName + ' ' + lastName;
}
return firstName;
}
对象类型
对象类型用来描述对象对应的结构,即有什么类型的属性和方法
JS中的对象:
const stu = {
name : 'Rose',
age : 18,
say(){ //对象中可以省略: function
console.log(this.name + 'say Hello TS');
}
}
TS中的对象类型:
const stu: {name: string,age: number,say(): void} = {
name : 'Rose',
age : 18,
say(){
console.log(this.name + 'say Hello TS');
}
}
-
使用{}描述对象的结构,属性采用
属性名:类型
的形式,方法采用方法名():返回值类型
的形式。 -
如果方法有参数,就在方法名后的小括号内指定参数的类型:
say(content: string): void
-
在一行中指定多个属性时,可以用
,/;
分割 -
方法的类型也可以使用箭头函数的形式
const stu: {name: string, age: number, say:(content: string) => void} = {
name : 'Rose',
age : 18,
say(content){
console.log(this.name + 'say Hello TS');
}
}
- 对象的属性/方法如果是可选的,使用
?
声明
接口
当一个对象类型被多次使用的时候,可以使用 接口 interface 描述对象的类型,达到 复用
//interface描述对象类型
interface User{
name : string,
age : number,
say?(): void
}
//复用interface声明的类型
const user1: User = {
name : 'Rose',
age : 18,
say(){
console.log(this.name)
}
}
-
接口中使用 interface 关键字声明,接口名称可以是任意合法的变量名称
-
接口中定义的属性和方法,结尾使用
,/;
分割,如果一行只有一个属性,后面也可以不写分号
type声明的类型别名也可以为对象指定类型:
type userType = {
name: string,
age?: number,
say(): void
}
let userByType:userType = {
name: 'zhangsan',
say() {
console.log('Hello TS')
}
}
-
相同点:都可以给对象指定类型
-
不同点:
- interface只能为对象指定类型
- type可以为任意类型指定别名
类型推论
-
在TS中,有些没有明确指出类型的地方,类型推论会帮助提供类型
-
由于类型推论的存在,在某些地方,类型注解可以省略
-
常见场景:
-
声明变量并初始化
-
决定函数返回值时
泛型
泛型函数
//<T> 声明泛型方法
function add<T>(a:T,b:T): T{
return a + b;
}
调用泛型方法:
add<number>(1,2);
add<string>(1,2);