0929 NOTE

2021/9/29 23:10:44

本文主要是介绍0929 NOTE,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

0929 NOTE–TS学习

定义

js的超集,可以在任何浏览器、计算机和操作系统上运行,但是执行时会先编译成js代码执行。

优势

①、有些错误如:未传参,js在浏览器中编译运行时才会报错,而ts在代码执行前便会报错提示

②、代码提示友好程度更高

③、代码中变量的类型声明使语义更清晰易懂

环境搭建

安装ts:

npm i typescript -g  /  yarn add typescript -g

编译ts文件:

tsc demo.ts		//执行后编译生成一个js文件,执行

插件:

npm i ts-node  / yarn add ts-node

插件安装后不需要编译啊,直接ts-node demo.ts即可执行

静态类型

给变量声明定义静态类型后,变量类型固定不可修改,变量具有该静态类型的所有属性和方法

基础类型和对象类型

基础类型:

//null , undefined , symbol , boolean , void 
const count:number = 123;
const teacherName:string = "john";

对象类型:

const teacher : {
	name:string;
	age:number;
}

const numbers:number[] = [1,2,3]	//数组类型,元素必须为number类型

const getTotal : () => number = () => {
	return 666; 
}
//函数类型,必须返回一个number类型的结果

类型注解和类型推断

type annotation 类型注解 声明变量时,定义类型,告知TS,该变量类型

type inference 类型推断 声明变量时,不定义类型,TS根据变量值推测变量类型

let count: number = 123;
let cpunt = 123;

注:当确定TS可以分析推断出变量类型时,可以选择类型推断,简化代码,但是当TS无法分析推断出变量类型时,需要类型注解

const firstnum = 1;
const secondnum = 2;
const sum = firstnum + secondnum;	//此时可以选择类型推断实现简化代码

function count(firstnum:number, secondnum:number){
    return firstnum + secondnum;
}

const sum = count(firstnum , secondnum);	//此时需要类型注解,因为TS无法推测传入参数的类型

实际无论类型注解和类型推断,目的都是让变量有一个具体类型

TS的每一个变量以及每一个对象的属性的类型都是固定的

TS函数相关类型

function count(firstnum:number, secondnum:number):number{	
    //此处第三个注解是为了防止失误导致返回结果与预期不符
    //return firstnum + secondnum + '';
    return firstnum + secondnum;
}

const sum = count(firstnum , secondnum);	
function sayHello():void{	//void类型表示无返回值
	console.log("hello")
}
function errorEmitter():never{	//error类型表示该函数永远无法执行完,而是执行部分
	throw new Error();
	console.log(123);
}
//函数参数解构
//参数传入对象时,在传入时解构

//js
function sum({firstnum,secondnum}){
	return firstnum + secondnum;
}
let result = sum({first:1,second:2})

//ts
function sum({firstnum,secondnum}:{firstnum:number,secondnum:number}):number{
	return firstnum + secondnum;
}
let result = sum({first:1,second:2})
//箭头函数的两种写法
//传入参数为字符类型,返回结果为数值类型
const func = (str:string) => {
	return parseInt(str,10);
}

const func1:(str:string) => number = (str) => {
    return parseInt(str,10);
}

函数编写时,入参一般需要类型注解,但是返回值往往可以通过类型推断简写

//当一个变量在初始和后续类型不同时,可以通过同时声明多种类型解决
let count : number | string = 123;
count = "123";

数组与元组

数组

const mixArr: (number | string)[] = [1,2,'3'];
const stringArr : string[] = ['1','2','3'];
const undefinedArr : undefined[] = [undefined];

//类型别名 type alias	便于理解
type User = { name:string;age:number};

const objectArr : User[] = [{
	name:'kaige',
	age:18
}]

元组

tuple

//数组
const stipulateArr : (string | number)[] = ['kaige',18,'22']
//元组
//约束规定了数组每项对应的类型
//数组的长度,每个元素对应类型固定时,选择元组会更便于管理
const stipulateArr : [string,number,number] = ['kaige',18,22]

Interface接口

定义通用类型

与类型别名的区别:只能代表函数或对象,无法代表基础类型

interface Person{
	name:string;
    readonly age?:number;	//?:语法,表示age属性可有可无,即使传参不具有age属性,也不会报错	readonly只读,不可修改
}

type Person1 = string;

const getPersonName = (person:Person) => {
	console.log(person.name)
}

const setPersonName = (person:Person,name:string) => {
	person.name = name;
}

注意:当以字面量形式将对象作为参数传入时,一定要符合类型注解,不能有多余属性,否则会报错

interface Person{
	name:string;
    age?:number;	
}

interface newPerson{
	name:string;
    age?:number;
    [propName:string]:any;	//表示可以存在其他属性,属性名类型为字符,值类型随意
	test():string	//方法,返回结果为字符类型
}

const person = {
	name:'kaige',
	gender:'male'
}

const getPersonName = (person:Person) => {
	console.log(person.name)
}

getPersonName(person);	//不报错
getPersonName({
	name:'kaige',
	gender:'male'
});		//报错	对象字面量传参会进行强校验

//class应用接口
class User implements Person{
    name = "kaige";
    test(){
        return 'aaa'
    }
}

//接口定义函数类型
interface test{
    ():void
}	//无参无返回值的函数

let kg : test = () => {
  console.log('kaige');
}

kg();

接口interface实际只是TS帮助做语法校验的工具,在编译转化成js代码时,interface的语句会被剔除

类的定义与继承

class Person {
	name = 'kaige';
	getName(){
		return this.name;
	}
}

const person = new Person();
console.log(person.getName());

super的常用:在子类重写父类方法后,可以通过super调用父类的该方法

类中的访问类型和构造器

//三种访问类型:private	protected	public
//public	允许在类的内外被调用
//private	允许在类内被调用
//protected	允许在类内及继承的子类中使用
//constructor
 class Person {
     constructor(public name:string){}
 }

//等价于
 class Person {
    public name:string;
    constructor(public name:string){
        this.name = name
    }
 }

//ts中,调用父类的构造函数时,如果父类的构造函数需要传入参数,还要按照父类构造函数的类型注解规则传入参数,否则会报错

class Teacher {
    constructor(public name : string){}
}

class Student extends Teacher {
    constructor(public age : number){
        super('kaige')
    }
}

let kg = new Student(22);
console.log(kg.name,kg.age)

类的getter和setter

//作用:调用私有属性,给类的私有属性加密保护
//单例模式
class Parent {
  private static kaige:Parent;	//私有化静态属性kaige,Parent类型,只能类内部调用
  private constructor(public name : string){};	//私有化构造函数,无法通过new创建新实例
  static newParent(){	//静态方法newParent,只能类本身调用
    if(!this.kaige) this.kaige = new Parent('kaige');	
    return this.kaige;
  }	//属性挂载在类身上,实现类似构建新实例对象的效果
}	

let child1 = Parent.newParent();
let child2 = Parent.newParent();	
console.log(child1.name,child2.name)	//kaige kaige
console.log(child1 === child2);		//true
//单例模式,获取的是同一个实例对象kaige,第一个实例对象kaige是new构造的

抽象类

//抽象类只能被继承,不能被实例化
//将共用性的属性、方法抽离成类进行封装
abstract class Graph{
  abstract getArea() : number
}

class Circle extends Graph{
  getArea(){
    return 123;
  }
}

class Triangle extends Graph{
  getArea(){
    return 123;
  }
}

class Square extends Graph{
  getArea(){
    return 123;
  }
}

interface Teacher {
  name:string;
}

interface Student extends Teacher {
  age : number;
}

interface People extends Teacher {
  gender : string;
}

let teacher = {
  name : 'wanggang',
}

let student = {
  name : 'kaige',
  number : 18,
}

let people = {
  name : 'xiaopang',
  gender : "male"
}

function getName(User : Teacher | Student | People){
  console.log(User.name)
}
//简写
function outputName(User : Teacher){
  console.log(User.name)
}

getName(teacher);
getName(student);
getName(people);

outputName(teacher);
outputName(student);
outputName(people);



这篇关于0929 NOTE的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程