一、TypeScript是什么?
Typed JavaScript at Any Scale: 添加了类型系统的JavaScript,使用于任何规模的项目。
两个重要特点:
-
类型系统
-
任何规模
中文官网:文档简介 · TypeScript中文网 · TypeScript——JavaScript的超集
TypeScript和javascript的区别
TypeScript 是JavaScript 对象的扩展。
JavaScript 代码可以在无需任何修改的情况下与 TypeScript 一同工作,同时可以使用编译器将TypeScript 代码转换为 JavaScript。
TypeScript 通过类型注解提供编译时的静态类型检查。
TypeScript 中的数据要求带有明确的类型,JavaScript不要求。
TypeScript 为函数提供了缺省参数值。
TypeScript 引入了 JavaScript 中没有的“类”概念。
TypeScript 中引入了模块的概念,可以把声明、数据、函数和类封装在模块中。
TypeScript的优点
静态输入
静态类型化是一种功能,可以在开发人员编写脚本时检测错误。查找并修复错误是当今开发团队的迫切需求。有了这项功能,就会允许开发人员编写更健壮的代码并对其进行维护,以便使得代码质量更好、更清晰。
大型的开发项目
有时为了改进开发项目,需要对代码库进行小的增量更改。这些小小的变化可能会产生严重的、意想不到的后果,因此有必要撤销这些变化。使用TypeScript工具来进行重构更变的容易、快捷。
更好的协作
当发开大型项目时,会有许多开发人员,此时乱码和错误的机也会增加。类型安全是一种在编码期间检测错误的功能,而不是在编译项目时检测错误。这为开发团队创建了一个更高效的编码和调试过程。
更强的生产力
干净的 ECMAScript 6 代码,自动完成和动态输入等因素有助于提高开发人员的工作效率。这些功能也有助于编译器创建优化的代码。
TypeScript特性
类型批注和编译时类型检查 :在编译时批注变量类型
类型推断:ts中没有批注变量类型会自动推断变量的类型
类型擦除:在编译过程中批注的内容和接口会在运行时利用工具擦除
接口:ts中用接口来定义对象类型
枚举:用于取值被限定在一定范围内的场景
Mixin:可以接受任意类型的值
泛型编程:
名字空间:名字只在该区域内有效,其他区域可重复使用该名字而不冲突。
元组:元组合并了不同类型的对象,相当于一个可以装不同类型数据的数组。
那么哪些项目适合用 TypeScript 开发呢:
-
需要多人合作开发的项目
-
开源项目,尤其是工具函数或组件库
-
对代码质量有很高要求的项目
二、TypeScript的安装
npm install -g typescript
检查版本:
tsc -v
ts的文件后缀一般就是.ts 用 TypeScript 编写 React 时,文件后缀为 .tsx。
TypeScript的执行,新增helloworld.ts文件:
(()=>{
function sayhi(name:String){
return '你好!'+name;
}
sayhi('张三');
})()
手动编译:tsc *.ts
tsc ./helloworld.ts
自动编译:
tsc --init
修改tsconfig.json
"outDir": "./js", //指定js文件的输出目录
"strict": false, //取消严格类型检查模式
执行监视任务:(自动跟踪代码)
终端–> 运行任务->显示所有任务–>tsc: 监视 tsconfig.json
自动在js目录下创建helloworld.js
(function () {
function sayhi(name) {
return '你好!' + name;
}
sayhi('张三');
})();
三、TypeScript基础
原始数据类型
JavaScript的数据类型有基本数据类型(Primitive Data Types)和对象数据类型(Object Types)。
基本数据类型包括:字符、数字、布尔、null、 undefined已经ES6中的Symbol和ES10的BigInt。
let num:Number=100;
// num =''; 报错,数据类型不匹配
num =55;
function show(a:string){
console.log(a);
}
// show(22) 报错
show('hello');
//布尔值
let flag:boolean = false;
//string
let msg:string = '哈哈';
//number
let a:number=10; //十进制
let b:number=0b101;//二进制
let c:number=0o10;//八进制
let d:number=0xA;//十六进制
console.log(a); // 输出: 10
console.log(b); // 输出:5
console.log(c); // 输出:8
console.log(d); // 输出:10
对象数据类型
undefined 和null(基本不用,作为了解)
let m:undefined=undefined;
let n:null=null;
//m=100; 报错
//n='a';
n=undefined;
m=null;
console.log(m); // null
console.log(n); // undefined
console.log(m==n);//true
console.log(m===n);//false
//undefined null 可以做为其它数据类型的子类型
let x = null;
let y = undefined;
console.log(x); // null
console.log(y); // undefined
数组:
//定义数组
let arr1 = [1, 2, 3];
console.log(arr1);
//泛型数组
let arr2 = ["hello", "你好", "good"];
console.log(arr2);
对象:
let obj:object={};
// obj=''; 错误
// obj=100; 错误
obj=null;
obj=undefined;
obj=new Array();
obj=new String();
obj=new Date();
obj=Number;
obj=Boolean;
obj=String;
any:任何类型
let h:any=22;
h='';
h=false;
h=2.3;
h=null;
let arr3:any[]=[1,2,3,'hello'];
void: 空值或没有返回值的函数
//void : 空值或没有返回值的函数
function fun1(): void{
console.log("void");
}
console.log(fun1());//输出undefined
类型推断
//类型推断:在类型不明确的情况下,推测一个类型
// 两种情况:
// 情况一:定义变量时由赋值的数据类型决定。
let num1=34;
// num1=""; 报错
//情况二:定义变量时不赋值
let g;
g=22;
g=null;
g='hello'
g=true;
联合类型
联合类型(Union types) 是指取值可以是多种类型中的一种。
//可以是多种数据类型之一
let f: boolean | number ;
f=true;
f=0;
//联合类型只能访问共有属性或方法
function fun2(something: string|number){
// return something.length; 错误 number没有length
return something.toString;//可以访问number和string共有属性:toString
}
对象类型-接口
在面向对象编程中,接口(Interface)是个非常重要的概念,接口是对行为(做什么)的抽象。而具体的实现(如何做)是由类(classes)去实现(implement)。
TypeScript中的接口是一个非常灵活的概念,除了对类的行为进行抽象以外,还可以对对象进行描述,例如:
//对象类型
//定义接口
interface Person{
readonly id:number //我们可以通过readonly定义只读属性(创建时赋值,其值不能被修改)
name: string
age: number
sex: string
address ?: string //可选属性使用?
[propName:string]:any //任意属性,任意值
}
//创建对象
let p: Person={
id: 9527,
name:'张三',
sex:'男',
age: 20,
city: '北京' //对应任意属性
}
console.log(p);
p.age=21;
// p.id=9221 错误不能修改只读属性
console.log(p)
函数类型-接口
//定义函数接口
interface search{
(x:string,y:string):boolean
}
const fun:search = function(a:string,b:string):boolean{
if(a===b){
return true;
}
return false;
}
console.log(fun('hi','hi'));
console.log(fun('abc','ABC'));
函数
JavaScript函数分为函数声明和函数表达式:
// JavaScript中的函数声明:命名函数
function add(a, b) {
return a + b;
}
//JavaScript中的函数表达式:匿名函数
let sum = function (a, b) {
return a + b;
};
console.log(add(11, 22));
console.log(sum(1, 2));
TypeScript的函数声明和函数表达式(声明类型)
//TS的函数声明
function add(a:number,b:number):number{
return a+b;
}
//TS的函数表达式
let sum1= function(a:number,b:number):number{
return a+b;
}
//TS的函数表达式完整写法
let sum2:(a:number,b:number)=>number = function(a:number,b:number):number{
return a+b;
}
console.log(add(22,33));
console.log(sum1(3,5));
console.log(sum2(1,1));
函数的默认参数和可选参数:
let myarr= function(a:string,b?:string,c:string='你好'){
return a+b+c;
}
console.log(myarr('李四')); //李四undefined你好
console.log(myarr('李四','晚上'));//李四晚上你好
剩余(可变)参数:
//剩余参数:可变参数
function show(x:string,y:string,...arr:number[]){
console.log(x+y+arr);
}
console.log(show('aaa','bbb',1,2,3));
函数重载:overload
//函数重载
function newSum(x:number,y:number):number;
function newSum(x:string,y:string):string;
function newSum(x:string|number,y:string|number):string|number{
if(typeof(x) =='string' && typeof(y)=='string'){
return x+y;
}
if(typeof(x) =='number' && typeof(y)=='number'){
return x+y;
}
}
console.log(newSum(11,22));
console.log(newSum('八','戒'))
类型断言:
//类型断言
function getLength(x:string| number):number{
if((x as string).length){
return (<string>x).length;
}else{
return x.toString().length;
}
}
console.log(getLength(1234));
console.log(getLength('hello'));
//window.a = 10 ; 报错
//通过any进行类型断言
//(window as any).a=10;
//将any类型断言为具体类型
function abc(x:any,y:any):any{
return x+y;
}
let m1 = abc(1,2)as number;
console.log(m1);
let m2 = abc('aaa','bbb') as string;
console.log(m2);
四、TypeScript进阶
类型别名
语法:type 类型别名= 数据类型:
例如:
type s=string;
let m3:s='hello';
console.log(m3);
type all = string | boolean | number;
let x1: all = true;
let y1: all = 'good';
x1='yes';
y1=123;
字符串字面量类型
字符串字面量类型:字符串的取值只能是其固定的指定某一个。
type stringEnum = '张三' | '张三丰';
let name1: stringEnum = '张三丰'
元组
//元组:合并了不同的数据类型
let arr4: [string,number]= ['abc',33];
console.log(arr4[0].slice(1));
console.log(arr4[1].toFixed(2));
枚举:
enum sex{
男=1,
女,
人妖 = '女'.length+2
}
console.log(sex);
console.log(sex.男);
enum weekDay{
星期一, //常量项默认值为0,其后会自动加1
星期二,
星期三,
星期四,
星期五,
星期六,
星期日
}
console.log(weekDay);
console.log(weekDay.星期二);
//常量枚举: 不会被编译(不会生成js文件)
const enum Color{
red,
green,
blue
}
// 错误不可访问 console.log(Color);
console.log(Color.green);
declare enum Directions{
up,right,down,left
}
console.log(Directions.down);
对应的js文件:
var sex;
(function (sex) {
sex[sex["\u7537"] = 1] = "\u7537";
sex[sex["\u5973"] = 2] = "\u5973";
sex[sex["\u4EBA\u5996"] = '女'.length + 2] = "\u4EBA\u5996";
})(sex || (sex = {}));
console.log(sex);
console.log(sex.男);
var weekDay;
(function (weekDay) {
weekDay[weekDay["\u661F\u671F\u4E00"] = 0] = "\u661F\u671F\u4E00";
weekDay[weekDay["\u661F\u671F\u4E8C"] = 1] = "\u661F\u671F\u4E8C";
weekDay[weekDay["\u661F\u671F\u4E09"] = 2] = "\u661F\u671F\u4E09";
weekDay[weekDay["\u661F\u671F\u56DB"] = 3] = "\u661F\u671F\u56DB";
weekDay[weekDay["\u661F\u671F\u4E94"] = 4] = "\u661F\u671F\u4E94";
weekDay[weekDay["\u661F\u671F\u516D"] = 5] = "\u661F\u671F\u516D";
weekDay[weekDay["\u661F\u671F\u65E5"] = 6] = "\u661F\u671F\u65E5";
})(weekDay || (weekDay = {}));
console.log(weekDay);
console.log(weekDay.星期二);
// 错误不可访问 console.log(Color);
console.log(1 /* Color.green */);
console.log(Directions.down);
(未完,待续.....)