安装TypeScript环境
搞点前端框架基础,整个全栈的饭碗吃吃
在项目中安装TypeScript
进入项目目录下安装
npm install typescript --save-dev
D:\anglarProject\gavin>npm install typescript --save-dev
removed 1 package, and audited 917 packages in 1m
122 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
也可以在 全局中安装
npm install -g typescript
如果下载typescript时速度过慢,可以考虑换一个镜像源~国内镜像源
npm config set registry https://registry.npmmirror.com
TypeScript是js的超级集
开始一个新的项目来学习TypeScript的使用:
typescript的常用编译命令
首先学习一下typescript的语法:
我们要明确一点ts是js的超级,即ts是兼容js的,ts相对于js增加了一些功能:
类型批注和编译时类型检查
类型推断
类型擦除
接口
枚举
Mixin
泛型编程
名字空间
元组
Await
以下功能是从 ECMA 2015 反向移植而来:
类
模块
lambda 函数的箭头语法
可选参数以及默认参数
先来打印一下helloworld:
新建一个hello.ts文件,里面的内容如下:
const hello:string="hello_world"
console.log(hello)
用typescript来编译一下:
tsc hello.ts
用node来运行一下刚刚编译生成的js文件
D:\anglarProject>node hello.js
Hello World!
下面随便整一个html文件,引入hello.js
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>TypeScript学起来</title>
<script src="hello.js"></script>
</head>
<body>
<div>前路白云外,孤帆安可论</div>
</body>
</html>
我们可以同时编译多个ts文件(文件之间用空格隔开就好了)
tsc 常用的编译参数:
直接编译ts文件:
tsc 文件名.ts —>>会生成一个同名的js文件
将声明的变量给提取出来
tsc --declaration hello.ts
编译时会生成一个.d.ts文件
.d.ts文件的内容
为了编译时更加简洁,可以在编译时将注释给过滤掉
tsc --removeComments hello.ts
const hello : string = "Hello World!"
console.log(hello)
//这是注释文件
alert("hello")
var hi="你好世界"
alert(hi)
编译一下:
tsc --declaration --removeComments hello.ts
打开index文件可以体验一下
多个文件合并输出到一个文件
tsc hello.ts hi.ts --out hello.js
新建一个.ts文件,
function displayDate(){
document.getElementById("demo").innerHTML=Date();
}
index.html文件内容如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>TypeScript学起来</title>
<script src="hello.js"></script>
</head>
<body>
<div>前路白云外,孤帆安可论</div>
<p id="demo">点击按钮显示日期</p>
<button type="button" onclick="displayDate()">显示日期</button>
</body>
</html>
源代码存储以及代码对于每个位置映射关系的信息.map的文件:
.map的文件内容
有版本号,文件名,来源 映射关系—>>这映射关系四个字母一组,具体映射关系暂不去管他了
{"version":3,"file":"hello.js","sourceRoot":"","sources":["hello.ts","hi.ts"],"names":[],"mappings":"AAAA,IAAM,KAAK,GAAY,cAAc,CAAA;AACrC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;AAClB,QAAQ;AACR,KAAK,CAAC,OAAO,CAAC,CAAA;AAEd,IAAI,EAAE,GAAC,MAAM,CAAA;AAEb,KAAK,CAAC,EAAE,CAAC,CAAA;ACPT,SAAS,WAAW;IACnB,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC,SAAS,GAAC,IAAI,EAAE,CAAC;AAClD,CAAC"}
监视ts文件,在他们改变时重新编译
tsc --watch
tsc hello.ts hi.ts --declaration --sourcemap --removeComments --out hello.js --watch
注意:watch要放在最后
typescript的一些特点
1,typejs会忽略程序中的空格,制表符,换行符
2,typejs区分大小写
3,结束符分号是可选的,(如果语句写在一行上,是需要分隔符的)
typejs中的注释
单行注释 //
多行注释/* */
在编译时可以忽略掉注释
tsc --removeComments
TypeJs面向对象的戏码
这个就很java了
对象,类,方法…
整呗~~新建一个ts文件,
//这是一个类
class hello{
//这是一个变量
name ="我是一个粉刷匠"
//这是一个构造方法
constructor ( ){
}
//这是一个方法
printName():string{
return this.name
}
}
//实例化
var obj=new hello();
//打印
console.log(obj.printName());
运行生成的js文件
D:\anglarProject>node ty.js
我是一个粉刷匠
编译之后生成的js文件:
//这是一个类
var hello = /** @class */ (function () {
//这是一个构造方法
function hello() {
//这是一个变量
this.name = "我是一个粉刷匠";
}
//这是一个方法
hello.prototype.printName = function () {
return this.name;
};
return hello;
}());
//实例化
var obj = new hello();
//打印
console.log(obj.printName());
看起来ts文件确实要比js好写一些
TS基础数据类型:
any —>>任意类型
任意值类型可以让这些变量跳过编译阶段的类型检查
let yyds:any =1
console.log(yyds)
yyds ="我就是一个string类型"
console.log(yyds)
yyds=true
console.log(yyds)
let ds:string="long ranger"
ds="我只能是字符串了"
console.log(ds)
生成的js文件:
//类型推断
var yyds = 1;
console.log(yyds);
yyds = "我就是一个string类型";
console.log(yyds);
yyds = true;
console.log(yyds);
var ds = "long ranger";
ds = "我只能是字符串了";
console.log(ds);
let x: any = 4;
x.ifItExists(); // 正确,ifItExists方法在运行时可能存在,但这里并不会检查
x.toFixed(); // 正确
number–>>数字类型 可以表示整数和小数
string -->>字符串
单引号和双引号都可以,
注意:使用反引号时可以定义多行文本和内嵌表达式
boolean -->>布尔类型
var name1 = "Hello";
var years = 5;
var words
words = `您好,我是 ${ name1 } 年纪 ${ years + 1} `;
console.log(words)
编译后生成的js文件:
var name1 = "Hello";
var years = 5;
var words;
words = "\u60A8\u597D\uFF0C\u6211\u662F ".concat(name1, " \u5E74\u7EAA ").concat(years + 1, " ");
console.log(words);
在新版本的typejs中,有一个关键字 let
var name1 = "Hello";
var years = 5;
var words
words = `您好,我是 ${ name1 } 年纪 ${ years + 1} `;
console.log(words)
let helo:string ="haha"
//数字类型
let size:number=100
//反引号
let result:string =`这就是个测试 ${helo} 数字是${size}`
//布尔类型
let bool:boolean=true
console.log(bool)
console.log(result)
编译后生成的js
var name1 = "Hello";
var years = 5;
var words;
words = "\u60A8\u597D\uFF0C\u6211\u662F ".concat(name1, " \u5E74\u7EAA ").concat(years + 1, " ");
console.log(words);
var helo = "haha";
//数字类型
var size = 100;
//反引号
var result = "\u8FD9\u5C31\u662F\u4E2A\u6D4B\u8BD5 ".concat(helo, " \u6570\u5B57\u662F").concat(size);
//布尔类型
var bool = true;
console.log(bool);
console.log(result);
数组类型,元组,枚举
let arr:number[]=[1,2,3,4,5];
console.log(arr)
//泛型数组
class Person{
public name:string
public age:number
constructor ( name:string, age:number){
this.name=name
this.age=age
}
}
let arr2:Array<Person>=[new Person("Sofia",26),new Person("Halo",28)]
console.log(arr2)
//元组 元素顺序对应的数据类型要一致
let xx:[string,number,boolean]
xx=["hello",100,true]
console.log(xx)
console.log(xx[0])
//枚举
enum Color{red,green,blue};
let r:Color=Color.red
console.log(r)//打印数字
//方法
function printData():void{
console.log("随便玩一下")
}
function printD(name:string):string{
return name
}
console.log(printD("amazing"))
编译后运行:—>>
生成的js文件:
var arr = [1, 2, 3, 4, 5];
console.log(arr);
//泛型数组
var Person = /** @class */ (function () {
function Person(name, age) {
this.name = name;
this.age = age;
}
return Person;
}());
var arr2 = [new Person("Sofia", 26), new Person("Halo", 28)];
console.log(arr2);
//元组 元素顺序对应的数据类型要一致
var xx;
xx = ["hello", 100, true];
console.log(xx);
console.log(xx[0]);
//枚举
var Color;
(function (Color) {
Color[Color["red"] = 0] = "red";
Color[Color["green"] = 1] = "green";
Color[Color["blue"] = 2] = "blue";
})(Color || (Color = {}));
;
var r = Color.red;
console.log(r); //打印数字
//方法
function printData() {
console.log("随便玩一下");
}
function printD(name) {
return name;
}
console.log(printD("amazing"));
现在有点体会到了,ts语言的定义方式某些程度上更倾向于java的风格
**null **
表示对象值缺失。
在js中null也是一种是数据类型,表示一个空对象
我们用type来检测null时,返回的是个object
console.log(typeof(null))
console.log(typeof(typeof(null)))
编译后:
console.log(typeof(null))
console.log(typeof(typeof(null)))
let size:number
size=10
size=undefined
size=null
console.log(size) //null
undefined
用于初始化变量为一个未定义的值
console.log(typeof(null))
console.log(typeof(typeof(null)))
let size:number
size=10
size=null
size=undefined
console.log(size) //undefined
never
never 是其它类型(包括 null 和 undefined)的子类型,代表从不会出现的值。
let yyds:never
let num:number
//yyds=100 编译不通过,数字不能转never类型
num=(()=>{throw new Error("抛个异常")})();
yyds=(()=>{throw new Error("never类型可以赋值给数字类型")})();
function err(msg:string):never{
throw new Error("抛个异常")
}
function deadloop():never{
while(true){
}
}
js文件
var yyds;
var num;
//yyds=100 编译不通过,数字不能转never类型
num = (function () { throw new Error("抛个异常"); })();
yyds = (function () { throw new Error("never类型可以赋值给数字类型"); })();
function err(msg) {
throw new Error("抛个异常");
}
function deadloop() {
while (true) {
}
}
JavaScript let 和 const
JavaScript let 和 const
ECMAScript 2015(ECMAScript 6)
ES2015(ES6) 新增加了两个重要的 JavaScript 关键字: let 和 const。
let 声明的变量只在 let 命令所在的代码块内有效。
const 声明一个只读的常量,一旦声明,常量的值就不能改变。
在 ES6 之前,JavaScript 只有两种作用域: 全局变量 与 函数内的局部变量。
简单来说 使用var 声明的变量 相当于全局的变量,在代码块中修改 该变量会影响该值
如果是用let声明,那么该变量只在所在代码块中起作用;
TypeScript中的变量声明
//变量的声明
var names : string ="小明"
console.log(names)
var age : number
console.log(age)//因为变量没有初始值此时值为undifined
//带类型推断的
var color="RED"
enum Colors{red,green,blue};
var c=Colors.red
console.log(c)
TypeScript 遵循强类型,如果将不同的类型赋值给变量会编译错误,
var num:number = “hello” // 这个代码会编译错误
类型断言:
类型断言可以用来手动指定一个值得类型,即允许变量从一种类型更改为另一种类型,
//变量的声明
var names : string ="小明"
console.log(names)
var age : number
console.log(age)//因为变量没有初始值此时值为undifined
//带类型推断的
var color="RED"
console.log(typeof(color))
enum Colors{red,green,blue};
var c=Colors.red
console.log(c)
//这里声明一个字符串数字,
var str ='100'
//通过断言来转换为数字类型,但是底层依旧是
var str2:number=<number> <any> str
console.log(str2)
console.log(typeof(str2))//这里类型依旧是string
let num:number =100
console.log(typeof(num))
编译后运行
这里可以发现断言之后的数据类型并没有转换成number类型, 是因为转换通常意味着某种运行时的支持,java中可以通过
String.valueOf()
Integer.valueOf() 来进行类型转换
类型推断
var name;//声明时没有赋值,没有确定数据类型
name="string" //这里类型推断
name=100//这里报错,因为第二行已经能够确定数据的类型了
变量作用域
var name2;//声明时没有赋值,没有确定数据类型
name2="string" //这里类型推断
//name2=2100//这里报错,因为第二行已经能够确定数据的类型了
var global_num=12
class Demo{
num =13;
static size=10;
storeNum():void {
var local_num=14
}
}
console.log("全局变量为: "+global_num)
console.log(Demo.size) // 静态变量
var obj = new Demo();
console.log("实例变量: "+obj.num)
编译后 运行
TypeScript中的运算符
说一下负号运算符:
var num12=100
var y= -num12
console.log(num12)
console.log(y)
TypeScript中的循环
var num =1
for(;num<=10;num++){
console.log(num)
}
var arr =[1,2,3,4,5,6,7,8,9]
for (let index = 0; index < arr.length; index++) {
const element = arr[index];
if (element==6){
break;//跳出循环
}
console.log(element);
}
TypeScript中的函数
带参数的函数:
function add(x :number,y:number):number{
return x+y
}
console.log(add(10,100))
可选参数:
参数名后用?表示该参数可选
function add(x :number,y:number):number{
return x+y
}
console.log(add(10,100))
function printData(x:string ,y:number,z?:string){
console.log(x,y,z)
}
printData("你好",12)
printData("hello",19,"world")
参数默认值
function add(x :number,y:number):number{
return x+y
}
console.log(add(10,100))
function printData(x:string ,y:number,z:string="世界"){
console.log(x,y,z)
}
printData("你好",19)
printData("hello",20,"world")
当我们第三个参数不传时,会使用默认值
定义方式为: 参数名:类型 =value
可选参数必须跟在必需参数后面。
参数不能同时设置为可选和默认。
PS D:\anglarProject> node .\fun.js
110
你好 19 世界
hello 20 world
可变参数:
function selection(str:string,...m:string[]){
console.log(str,m)
}
selection("hello","world","你好","北京欢迎你")
function sprint(...str:any[]){
console.log(str)
}
sprint("他不懂你的心","骑自行车的风景")
编译后运行:
hello [ 'world', '你好', '北京欢迎你' ]
[ '他不懂你的心', '骑自行车的风景' ]
TypeScript匿名函数
匿名函数自调用
//匿名函数
var func=function(str:string):string{
return str
}
console.log(func("匿名函数"));
(function():void{
var str="hellohahaha"
console.log(str)
})();//函数自调用
//带有参数的函数自调用
(function (str:string):string{
console.log(str)
return str
})("hello");
编译后生成的js文件:
//匿名函数
var func = function (str) {
return str;
};
console.log(func("匿名函数"));
(function () {
var str = "hellohahaha";
console.log(str);
})(); //函数自调用
//带有参数的函数自调用
(function (str) {
console.log(str);
return str;
})("hello");
TypeScript构造函数
class Person{
name :string
hobby :string
constructor(name:string,hobby:string){
this.name=name
this.hobby=hobby
}
}
var per =new Person("张三","跑步")
console.log(per)
class MathAdd{
constructor(a:number,b:number){
}
}
//Function是一个接口 直接new一个该接口,传入 string[]类型的参数 然后定义返回值
var myFunction = new Function("a", "b", "return a * b");
var x = myFunction(4, 3);
console.log(x);
// var obj=new MathAdd("a","b","return a + b");
var test = new Function("a","b","return a + b")
console.log(test(10,12))
// 递归调用
function factorial(number) {
if (number <= 0) { // 停止执行
return 1;
}
else {
return (number * factorial(number - 1)); // 调用自身
}
}
;
console.log(factorial(6)); // 输出 720
TypeScript中lambda表达式
// lambda函数
var fool =(s:number)=>100+x
console.log(fool)
console.log(fool(19))
var dtse=y=>{
// 参数类型让他自己去推断,或者给指定好
console.log(y)
}
var dtse2=y=>{
// 参数类型让他自己去推断,或者给指定好
if (typeof y =="string"){
console.log(y)
}else{
console.log("啥也不是")
}
}
dtse("大江大河")
dtse2("hell")
无参数时可以设置空括号:
var disp =()=> {
console.log("Function invoked");
}
disp();
TypeScript中函数重载
这个跟java中函数的重载逻辑是一样的
//函数重载
function disp(s1:string):void;
function disp(n1:number,s1:string):void;
function disp(x:any,y?:any):void {
console.log(x);
console.log(y);
}
disp("abc")
disp(1,"xyz")
//定义一个方法 隐式的返回any function add(a:number):any;
function add(a:number,b:string):void;
// 定义一个方法
function add(a:string,b:string,c:number):void;
// 实现 方法以便实现方法的重载
/**
* 如果参数类型不同,则参数类型应设置为 any。
* 参数数量不同你可以将不同的参数设置为可选。
*
* @param a
* @param b
*/
function add(a:any,b:string,c?:number):void{
}
函数重载:
1,如果参数类型不同,则参数类型应设置为 any。
2,参数数量不同你可以将不同的参数设置为可选。
Number对象
// NUmber中的函数
var size= new Number(100.789)
var niubi=size.toExponential();//把对象的值转换为指数计数法
console.log(niubi)
console.log(typeof(size.toFixed()))//string
console.log(size.toFixed(2)) //保留小数点后2位
console.log(size.toLocaleString)//当地的数字格式顺序
console.log(typeof(size.toPrecision()))
console.log(size.toPrecision(2))//把数字格式化指定长度
console.log(size.toPrecision(4))
console.log(size.toString(10))//
console.log(size.toString(2))//数字转换位字符串,可以指定进制
console.log(size.valueOf())//
String对象
//String
var st= new String("嘿嘿");
console.log(st.constructor)
console.log(st.length)
function employ(id:string){
}
var e= new employ("Hello")
//
employ.prototype.email="添加了属性email"
console.log(e.email)
console.log(st.charAt(2))//指定位置的字符
console.log(st.charCodeAt(2))//指定位置的字符 Unicode 编码。
console.log(st.concat("拼接字符串"))
st.match(/el/o) //匹配 查找找到一个或多个正则表达式的匹配。
st.replace("o","a")//替换
st.search("o")//查找
st.split("o")//分割
st.trim()
console.log(st.toLocaleLowerCase())
st.valueof()
//其他函数略
Array对象
//数组
var j;
var nums = [1001, 1002, 1003, 1004];
for (j in nums) {
console.log(nums[j]);
}
var arr = new Array(1,2,3,4)
var str =arr.join()
var str2 =arr.join("-")
console.log(str)
console.log(str2)
//遍历
arr.forEach(function (value){
console.log(value)
})
var arr1= new Array(5,6,7,8)
var newarr =arr.concat(arr1)//数组整合到一个数组中
newarr.forEach(function(value){
console.log(value)
})
/*
确定数组的所有成员是否满足指定的测试。
* @param predicate最多接受三个参数的函数。每个方法调用
*数组中每个元素的谓词函数,直到谓词返回一个值
*,它是布尔值false的强制值,或者直到数组结束。
* @param thisArg this关键字可以在谓词函数中引用的对象。
*如果省略thisArg,则使用undefined作为this值。
*/
function dayu5(ele ,_index,_array){
return (ele>=5)
}
// every(predicate: (value: T, index: number, array: T[]) => unknown, thisArg?: any): boolean;
console.log(newarr.every(dayu5))
// 过滤
function filterRes(ele ,index,array){
return (ele>=4)
}
console.log(newarr.filter(filterRes))
newarr.indexOf(7)//7的位置
//返回处理之后的数组
var narr=newarr.map(Math.sqrt)//通过指定函数处理数组的每个元素,并返回处理后的数组。
narr.forEach(function(value){
console.log(value)
})
// 向数组中添加元素
narr.push(100,200)
narr.pop()//从尾部移除,并返回该元素
arr.shift()//删除并返回数组的第一个元素。
arr.unshift(100,300)//像数组添加元素--一个,多个
narr.forEach(function(value){
console.log(value)
})
//将数组中元素按规则处理为一个值将 (从左到右)
var arrs=arr.reduce(function(a,b){
return a+b
})
//(从you到zuo)
var arrs=arr.reduceRight(function(a,b){
return a+b
})
console.log("arrs--"+ arrs)
arr.reverse()//反转数组
// 将数组--切除一块作为新数组
arr.slice(0,4)
arr.some(dayu5)//这个跟every()类似
arr.sort()
arr.splice(1,2)//从数组位置1开始删除两个元素