【专项学习】—— TypeScript基础语法入门
写在前面:推荐掘金-typescript万字入门文
一、TypeScript定义
①typescript是javascript的超级,同时它拥有静态的类型;
②typescript会被编译成普通的javascript代码,然后再去运行。
//js中为动态类型 let a = 123; a = '123'; //ts为静态类型 let b: number = 123; //(未来存储的类型 只能是数字类型) b = '123'; //报错 b = 456; //不报错
二、TypeScript带来了什么优势?
①开发过程中,发现潜在问题
②更友好的编辑器自动提示
③代码语义更清晰易懂
function demo(data){ return Math.sqrt(data.x ** 2 + data.y ** 2); } demo(); //js中线上运行才会发现错误 function tsDemo(data: { x: number, y: number}) { return Math.sqrt(data.x ** 2 + data.y ** 2); } tsDemo(); //vsCode编辑器会提示报错 tsDemo({x: 1, y:123}); //正确写法 // typescript类型自定义类型(别名语法) —— 使可读性更好 // type Point = { x: number, y: number } interface Point { x: number, y:number } function tsDemo(data: Point){ return Math.sqrt(data.x ** 2 + data.y ** 2); } tsDemo({ x: 1, y: 123 });
三、静态类型的深度理解
interface Point { x: number, y: number } //point变量上具备Point类型所有的属性和方法 const point: Point = { x: 3, y: 4 }
四.基础类型和对象类型
/基础类型 //number、string、boolean、null、undefined、symbol、void(空) const count : number = 123; const teacherName : string = 'Dell'; //对象类型 //对象、数组、函数 const teacher: { name: string, age: number } = { name: 'Dell', age: 18 }; //数组的每一项是数字 const numbers: number[] = [1, 2, 3]; class Person {} //dell必须是Person类对应的对象 const dell:Person = new Person(); //getTotal是一个函数,返回值是一个number const getTotal: () => number = () => { return 123; }
五.类型注解和类型推断
// type annotation 类型注解 我们来告诉TS变量是什么类型 let count: number; count = 123; // type inference 类型推断 TS会自动的去尝试分析变量的类型 let countInference = 123; // 如果 TS 能够自动分析变量类型,我们就什么也不需要做了 // 如果 TS 无法分析变量类型的话,我们就需要使用类型注解 const firstNumber = 1; const secondNumber = 2; const total = firstNumber + secondNumber; //可以类型推断出number类型 //函数参数需要 类型注解 具体的类型 function getTotal(firstNumber: number, secondNumber: number){ return firstNumber + secondNumber } const total = getTotal(1, 2); //可以类型推断出number类型
六.函数相关类型
//函数返回值类型约束为 number 类型 function add(first: number, second: number) : number { return first + second } const total = add(1, 2); //函数返回值为 void 类型 —— 空,函数没有返回值 function sayHello(): void{ console.log('hello'); } //函数返回值为never类型 —— 函数永远不会执行到最后 function errirEmitter(): never{ throw new Error(); console.log(123); //不会执行 } //函数参数是对象解构 —— 只要是解构,类型注解必须在{}里 function add( {first, second}: {first: number, second: number} ): number{ return first + second; } const total = add({ first: 1, second: 2 }); function getNumber({ first } : { first : number }) { return first; } const count = getNumber({ first: 1 });
七、数组和元组
//数组 const arr: (number | string )[] = [1, '2', 3]; const stringArr: string[] = ['a', 'b', 'c']; const undefinedArr: undefined[] = [undefined]; //类型别名 type alias type User = {name: string, age: number}; const objectArr: User[] = [{ name: 'dell', age: 28 }] class Teacher { name: string; age: number; } const objectArr: Teacher[] = [ new Teacher(); { name: 'dell', age: 28 } ]; //元组 tuple //数组的长度是固定的,数组中每一项的类型也是固定的 const teacherInfo: [string, string, number] = ['Dell', 'male', 18]; //csv const teacherList: [string, string, number][] = [ ['dell', 'male', 19], ['sun', 'female', 26], ['jeny', 'female', 38] ]
八、Interface接口
Interface是开发中,帮助我们进行语法提示、语法校验的工具,真正编译为js时会被剔除
//interface定义通用类型 —— 只能代表函数或对象,不能代表基础类型 interface Person { name: string; age?: number; //?表示age属性可有可无 //readonly sex: string; //readonly表示属性只能读 不能写入 [propName: string]: any; //person里多一个属性 不会报错 say(): string; } //Teacher类型 继承自 Person类型 interface Teacher extends Person { teach(): string } //interface定义函数的类型声明 interface SayHi { //参数是string类型,返回值是string类型 (word: string): string } //interface 和 type相类似,但并不完全一致 //type定义类型别名 —— 可以定义基础类型 type Person1 = string; const getPersonName = (person: Person): void => { console.log(person.name); }; const setPersonName = (person: Teacher, name: string): void => { person.name = name; } const person = { name: 'dell', sex: 'male', say() { return 'say hello'; }, teach() { return 'teach'; } } getPersonName(person); //person缓存变量直接传入,不严格,多一个属性不报错 getPersonName({ name: 'dell', sex: 'male' , //对象字面量直接传入,严格,多一个属性会报错 say() { return 'say hello'; } }) setPersonName(person, 'lee'); //类User 应用 接口Person —— 要求类里 必须有接口的属性和方法 class User implements Person { name = 'dell'; say() { return 'hello' } } const say : SayHi = (word: string) => { return word; }
九.类的定义和继承
class Person { name = 'dell'; getName() { return this.name; } } class Teacher extends Person { getTeacherName(){ return 'Teacher' } getName() { //当类覆盖父类的方法之后,使用super调用父类的getName方法 return super.getName() + 'lee'; } } const person = new Person(); console.log(person.getName()); const teacher = new Teacher(); console.log(teacher.getTeacherName());
十.类中的访问类型和构造器
①public 允许我在类的内外被调用
②private 允许在类内被使用
③protected 允许在类内及继承的子类中使用
//什么都不写,默认隐藏了public class Person { protected name: string; public sayHi() { this.name; console.log('hi'); } } class Teacher extends Person { public sayBye() { this.name; } } const person = new Person(); person.name = 'dell'; console.log(person.name); person.sayHi(); //constructor 构造器 class Person { //传统写法 //public name: string; //constructor(name: string) { //在new一个实例的瞬间被执行 // this.name = name; // } //简化写法 —— 初始化赋值 constructor(public name: string) {} } //如果父类、子类都有构造器,子类要手动调用一下父类的构造器,否则报错 class Teacher extends Person { constructor(age: number) { super('dell') //调用父类的构造函数时,要按父类的要求,传入参数 //如果父类是一个空类,没有构造器,也要调用super } } const person = new Person('dell') console.log(person.name); const teacher = new Teacher(28);
十一.静态属性,类里的Setter和Getter
①Getter get可用于加密,确保变量的安全性
②Setter set也可以帮助保护私有变量
class Person { constructor(private _name: string){ } get name() { return this._name + 'lee' } set name(name: string){ const realName = name.split(' ')[0]; this._name = realName; } } const person = new Person('dell'); console.log(person.name); person.name = 'dell lee'; console.log(person.name);
设计模式单例模式:一个类只允许通过这个类获取一个这个类的实例
class Demo { private static instance: Demo; //不允许外部直接通过new创建实例 private constructor(public name: string) {} //static指把方法直接挂在类上,而不是类的实例上面 static getInstance() { //返回一个Demo的唯一实例 if(!this.instance){ this.instance = new Demo('dell lee'); } return this.instance; } } const demo1 = Demo.getInstance(); const demo2 = Demo.getInstance(); //demo2和demo1是一个实例 console.log(demo1.name); console.log(demo2.name);
十二.抽象类
①抽象类是把类相关的东西抽象出来
abstract class Geom { width: number; getType() { return 'Gemo'; } abstract getArea(): number; } //子类继承自抽象类,必须具体化抽象类中的抽象方法 class Circle extends Geom { getArea() { return 123; } }
②接口是把对象等其它东西的通用抽象出来
interface Person { name: string } interface Teacher extends Person{ teachingAge: number; } interface Student extends Person{ age: number; } const teacher = { name: 'dell', teachingAge: 3 } const student = { name: 'lee', age: 18 } const getUserInfo = (user: Person) => { console.log(user.name); }; getUserInfo(teacher); getUserInfo(student);
注:课程源自慕课网
越是迷茫、浮躁的时候,保持冷静和耐心,尤为重要