TypeScript介绍
什么是TypeScript?
TypeScript是JavaScript的一个超集,支持ES6标准
TypeScript由微软开发的自由和开源的编程语言
TypeScript设计目标是开发大型应用,它可以编译成纯JavaScript,编译出来的JavaScript可以运行在任何浏览器上
TypeScript是一种由微软开发的自由和开源的编程语言。它是JavaScript的一个超集,而且本质上向这个语言添加了可选的静态类型和基于类的面向对象编程。
JavaScript 与 TypeScript的区别
TypeScript是JavaScript的超集,扩展了JavaScript的语法,因此现有的JavaScript代码可与TypeScript一起工作无需任何修改,TypeScript通过类型注解提供编译时的静态类型检查。
TypeScript 可处理已有的JavaScript代码,并只对其中的TypeScript代码进行编译。
TS中的数据类型
1基础数据类型
number类型:双精度64位浮点值。它可以用来表示整数和分数。
let num: number;
num = 100
console.log(num);
boolean类型:表示逻辑值:true和false。
let flag: boolean;
flag = true;
flag = false;
.string类型:一个字符系列,使用单引号()或双引号(")来表示字符串类型。反引号(`)来定义多行文本和内嵌表达式
let beauty: string;
let msg = "亚"
let dream = `女神是$(beauty)`
数值,字符串和布尔值是我们开发中最常使用的基础数据类型,与js中的数值,字符串和布尔完全一致,在ts中我们主要做类型校验使用
2.数组
数组:声明变量的一组集合称之为数组
数组是我们前端开发过程中,最常用的引用类型之一,再发送请求获取响应时,我们往往会使用到数组类型,因此我们务必要掌握好数组的集中定义方式
// 方式一
let beautyArr: string[];
beautyArr = ["刘亦菲", "刘诗诗", "安以轩"]
// beautyArr=["刘亦菲","刘诗诗","安以轩",100] 不可以传number
// 方式二
let numArr: Array<number>;
numArr = [1, 2, 3, 4, 5,];
// numArr=[1,2,3,4,5,"刘亦菲"]; 不可传string
// 联合类型
let myBeauty: (number | string | boolean)[];
myBeauty=["刘亦菲","刘诗诗","安以轩",100]
myBeauty=["刘亦菲","刘诗诗","安以轩",100,true]
3.元组
元组类型Tuple
TS中的元组类型其实就是数组类型的扩展
元组类型用来表示已知元素数量和类型的数组,各元素的类型不必相同,对应位置的类型需要相同
定义:['','',...]
作用:元组用于保存定长定数据类型的数据
let tup1:[string,number,boolean];
tup1=["关晓彤",25,true]
// tup1=[123,25,true]
// tup1=["关晓彤","关晓彤",true]
console.log(tup1);
4.any与void
any
any:表示任意类型,当我们不清楚某个值的具体类型的时候我们就可以使用any
在TS中任何数据类型的值都可以负责给any类型
使用场景
变量的值会动态改变时,比如来自用户的输入,任意值类型可以让这些变量跳过编译阶段的类型检查
改写现有代码时,任意值允许在编译时可选择地包含或移除类型检查
定义存储各种类型数据的数组时
//使用场景一
//变量的值会动态改变时,比如来自用户的输入,任意值类型可以让这些变量跳过编译阶段的类型检查
let temp: any;
temp = "刘亦菲";
temp = 18;
temp = true;
//使用场景二
//改写现有代码时,任意值允许在编译时可选择地包含或移除类型检查
let x: any = 4;
x.IfitExists();
console.log(x.toFixed());
//使用场景三
// 定义存储各种类型数据的数组时
let arr: any[] = [1, false, 'fine'];
arr[1] = 100;
void
void:当一个函数没有返回值时,你通常会见到其返回值类型是void
某种程度上来说,void类型像是与any类型相反,它表示没有任何类型。
在Ts中只有null和undefined可以赋值给void类型
定义了一个不可以保存任意类型数据的变量,只能保存null和undefined
注意点: null和undefined是所有类型的子类型,所以我们可以将null和undefined赋值给任意类型
//严格模式下会null报错
function makeMoney(): void {
console.log("I want to make much money and marry a wife! ! ! ");
}
makeMoney()
let test1: void;
// test1 ="刘亦菲";
// test1 =12;
// test1 =true;
// 严格模式下null不会报错
test1 =null;
test1 = undefined;
5.null与undefined
TypeScript里,undefined和null两者各自有自己的类型分别叫做undefined和null。和void相似,它们的本身的类型用处不是很大
非严格模式下,可以把 null和undefined赋值给number类型的变量。
let x: undefined = undefined;
let y: null = null;
// x="刘亦菲";
// x=28;
// y="刘亦菲";
// y=28;
let money: number = 100;
// 非严格模式下,可以把nu11和undefined赋值给number类型的变量。
money = null;
money = undefined;
6.never与object
never类型:
表示的是那些永不存在的值的类型;
never类型是那些总是会抛出异常或根本就不会有返回值的函数表达式或箭头函数表达式的返回值类型;
变量也可能是never类型,当它们被永不为真的类型保护所约束
注意点;never类型是任何类型的子类型,也可以赋值给任何类型,然而,没有类型是never的子类型或可以赋值给never类型(除了never本身之外)。
即使any也不可以赋值给never
function error(message : string): never{
throw new Error (message);
}
error("没了~~~")
//推断的返回值类型为never
function fail(){
return error( "GG了~~")
}
//返回never的函数必须存在无法达到的终点
function loop():never {
while(true)
{
//.
}
}
object类型:
object表示非原始类型,也就是除number ,string, boolean,symbol,null或undefined之外的类型
定义了一个只能保存对象的变量
我们后面更常用的是|接口与类型别名
let goddess:object;
// goddess=true;
// goddess="刘亦菲";
// goddess=18;
goddess={name: "刘亦菲",age: 18};
console. log(goddess);
7.枚举
enum类型是对javaScript标准数据类型的一个补充。像C#等其它语言一样,使用枚举类型可以为一组数值赋予友好的名字。
枚举用于表示固定的几个取值
enum Gender {
male,//男
female//女
}
let gender: Gender;
gender = Gender.male;
gender = Gender.female;
gender = "666";
gender = true;
gender = 10;// 枚举本身是一个数字
console.log(gender);
注意点:TS中的枚举类型的取值,默认是从上至下从o开始递增的·
虽然默认是从0开始递增的,但是我们也可以手动的指定枚举的取值的值
enum Gender {
male,//男
female//女
}
console.log(Gender.male);
console.log(Gender.female);
注意点:如果手动指定了前面枚举值的取值,那么后面枚举值的取值会根据前面的值来递增
enum Gender {
male,//男
female=5//女
}
console.log(Gender.male);//0
console.log(Gender.female);//5
enum Gender {
male=100,//男
female=200//女
}
console.log(Gender.male);//100
console.log(Gender.female);//200
enum Gender {
male,//男
female//女
}
console.log(Gender.male);//0
console.log(Gender[0]);// ?
const getNum=()=>200
let gender:Gender;
gender=Gender.female;
gender=100;
gender=getNum();
数字枚举
1.数字枚举的取值可以是字面量,也可以是常量,也可以是计算的结果
⒉.如果采用字面量对第一个成员进行赋值,下面的成员会自动递增
3.如果采用常量或计算结果进行赋值,则下面的成员也必须初始化
字符串枚举
1.如果采用字面量对第一个成员进行赋值,下面的成员也必须赋值
⒉采用[index]的形式不能获取到内容,需要传入[key]
3.字符串枚举不能使用常量或者计算结果给枚举值赋值
4.它可以使用内部的其它枚举值来赋值
enum Direction{
up="UP",
down="DOWN"
}
console.log(Direction.up);//UP
console.log(Direction.down);//DOWN
console.log(Direction[0]);//undefined
console.log(Direction["up"]);//UP
let x:Direction;
x=Direction.down;
x="左"; 不可以
const getDirection=()=>"右"
x=getDirection(); 不可以
异构枚举:枚举中既包含数字又包含字符串,我们就称之为异构枚举
如果是字符串枚举,那么无法通过原始值获取到枚举值
//枚举中既包含数字又包含字符串,我们就称之为异构枚举
//注意点:"如果是字符串枚举,那么无法通过原始值获取到枚举值
enum Gender {
male = 1,
female = "女"
}
console.log(Gender.male);
console.log(Gender.female);
console.log(Gender[1]);
console.log(Gender['女']);
8.bigint与symbol
bight类型:表示非常大的数
symbo1类型:表示全局唯一引用
ES2020可用
// bight类型:表示非常大的数
// symbo1类型:表示全局唯一引用
// ES2020可用
// bigint
const Hundred1 : bigint=BigInt(100)
const Hundred2 : bigint=100n
console.log(Hundred1)
console.log(Hundred2)
// symbol
let name1 =Symbol("name")
let name2 =Symbol("name")
// console.log(name1)
// console.log(name2)
if (name1===name2) {
console.log("一样")
} else {
console.log("不一样")
}
9.变量的声明与解构
与js中完全一致,我们简单复习—下解构
数组解构与对象解构
//数组解构
// let goddess=["邱淑贞","赵雅芝"];
// let [firstName,secondName]=goddess;
// console.log(firstName);
// console.log(secondName);
// let goddess=["赵今麦","蒋依依","古力娜扎","张子枫"];
// let[third,...rest]=goddess;
// console.log(third);
// console.log(rest);
// let goddess=["赵今麦","蒋依依","古力娜扎","张子枫"];
// let [,forth,,fifth]=goddess;
// console.log(forth);
// console.log(fifth);
//对象解构
let beauty={
uname : "杨超越",
age: 20,
sex: "女",
}
let {uname,age,sex} = beauty;
console.log(uname);
console.log(age);
console.log(sex);
10.类型断言
什么是类型断言?
类型断言可以用来手动指定一个值的类型,即允许变量从一种类型更改为另一种类型。
通俗的说就是我相信我自己在定义什么类型
语法格式
<类型>值
值 as 类型
let str:any ="世界上最遥远的距离就是,你是if而我是else,似乎一直相伴但又永远相离";
//方式一
let len=(<string>str).length
//方式二
let num=(str as string).length
console.log(len);
console.log(num);
function typeAs(x:number|string){
let len=(<string>x).length
//let len=(x as string)
console.log(len)
}
typeAs("世界上最遥远的距离就是,你是if而我是else,似乎一直相伴但又永远相离")
11.type别名
类型别名就是给一个类型起个新名字,但是它们都代表同一个类型
// 第一种
type zlwz = "张三"|"李四"|"王五"|"赵六"
let one:zlwz="李四"
// let two:zlwz=100
console.log(one)
// 第二种
type myfun = (a:number,b:number)=>number
let fun:myfun=(a:number,b:number)=>a+b
let result=fun(10,20)
console.log(result);
type myGoddass={
name: string,age: number,sex:boolean
}
let yifi:myGoddass={
name: "刘亦菲",
age:18,
// sex:"女",//报错,不符合定义的类型
sex:true
}
console.log(yifi);
接口
接口的基本信息
什么是接口?
接口是一系列抽象方法的声明,是一些方法特征的集合,这些方法都应该是抽象的,需要由具体的类去实现,然后第三方就可以通过这组抽象方法调用,让具体的类执行具体的方法
接口也是一种数据类型
格式:
interface interface_name {}
接口的基本使用
interface IFullName {
firstName: string
lastName: string
}
let goddassName: IFullName = {
firstName: "刘",
lastName: "亦菲"
}
console.log(goddassName.firstName, goddassName.lastName);
function say({ firstName, lastName }: IFullName): void {
console.log(`我的女神是${firstName}${lastName}`)
}
say(goddassName);
// say({name:"杨幂"})
可选属性与只读属性
可选属性使用:?
interface IFullName {
firstName: string
lastName: string
age?: number
}
let goddass: IFullName = {
firstName: "杨",
lastName: "超越",
// age:18
}
只读属性使用: readonly
interface IInfo {
readonly name: string
readonly age: number
}
let info: IInfo = {
name: "赵丽颖",
age: 18
}
// info.name="范冰冰";
// info.age=19;
readonly与const的区别:做为变量使用的话用const,若做为属性则使用readonly
索引签名
定义:索引签名用于描述那些"通过索引得到"的类型
//解决参数可多可少的问题
// 方案一:使用可选参数
interface IFullName {
firstName: string
lastName: string
age?: number
}
let goddass1: IFullName = { firstName: "刘", lastName: "亦菲", age: 18 }
let goddass2: IFullName = { firstName: "刘", lastName: "亦菲" }
//方案二:使用变量
let info = { firstName: "杨", lastName: "幂", age: 18, song: "爱的供养" };
let goddass3: IFullName = info;
//方案三:使用类型断言
let godass4: IFullName = ({ firstName: "杨", lastName: "幂", age: 18, song: "爱的供养", tv: "仙剑奇侠传三" }) as IFullName;
//索引签名
interface IBeauty {
[props: string]: string
}
let goddass5 = { name1: "刘亦菲", name2: "刘诗诗", name3: "赵丽颖" };
interface IAge {
[props: string]: number
}
let ages = { age1: 10, age2: 20, age3: 30 }
interface IMyFullName {
firstName: string
lastName: string
[props: string]: string
}
let goddass6: IMyFullName = { firstName: "刘", lastName: "亦菲", sex: "女" }
let goddass7: IMyFullName = { firstName: "刘", lastName: "亦菲", tv: "甄嬛传" }
函数接口
为了使用接口表示函数类型,我们需要给接口定义一个调用签名。
它就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每个参数都需要名字和类型。
//定义函数接口
interface IMakeMoney {
(salary: number, reward: number): number
}
let sum: IMakeMoney = function (x: number, y: number): number {
return x + y;
}
let res = sum(100, 1000);
console.log(res);
接口的继承
接口继承就是说接口可以通过其他接口来扩展自己。
Typescript 允许接口继承多个接口。
继承使用关键字extends。
//单继承
interface IPerson {
age : number
}
interface IName extends IPerson {
name : string
}
let lady : IName = {
name : "蒋依依",
age: 21
}
//多继承
interface IFatherMoney {
m1: number
}
interface IMotherMoney {
m2: number
}
interface ISonMoney extends IFatherMoney,IMotherMoney {
s1 :number
}
let money :ISonMoney = {
m1:100,
m2 : 100,
s1: 100}
console.log(`儿子一共有${money.m1 + money.m2 + money.s1}万元`);
接口与类型别名的异同
相同点:
都可以描述属性或方法
都允许拓展
// 1.都可以描述属性或方法
type womanStar = {
name: string
age: number
show(): void
}
interface IwomanStar {
name: string
age: number
show(): void
}
let star1: womanStar = {
name: "刘亦菲",
age: 18,
show() {
console.log("仙剑奇侠传一")
}
}
let star2: IwomanStar = {
name: "杨幂",
age: 18,
show() {
console.log("古剑奇谭")
}
}
//2.都允许拓展
type money = {
y1: number
}
type money2 = money & {
y2: number
}
let salary: money2 = {
y1: 10,
y2: 20
}
interface IStar1 {
name: string
}
interface IStar2 extends IStar1 {
age: number
}
let star: IStar2 = {
name: "范冰冰",
age: 18
}
不同点:
type可以声明基本数据类型,联合类型,数组等; interface只能声明变量
当出现使用type和interface声明同名的数据时;type会直接报错;interface会进行组合
type不会自动合并; interface会
// 1.type可以声明基本数据类型,联合类型,数组等
//interface只能声明变量
type t1 = number;
type t2 = number | string;
type t3 = [number | boolean]
// interface ITest=number
// 2.当出现使用type和interface声明同名的数据时
//type会直接报错
// type myName = {
// name: string
// }
// type myName = {
// name: string
// }
interface IMayName {
name: string
}
interface IMayName {
name: string,
age: number
}
let myName: IMayName = {
name: "库里",
age: 30
}