TypeScript语法基本类型(入门~放弃)

TypeScript入门初始了解

1、原始类型

// 小object 代表的是非原始类型 的类型 也就是不能是string number boolean  symbol  严格模式  多包括null undefined

let obj1: object = 3; // 报错
let obj2: object = "3"; // 报错
let obj3: object = true; // 报错
let obj4: object = null; // 报错
let obj5: object = undefined; // 报错
let obj6: object = Symbol(); // 报错
let obj7:object = {a: 1, b: '2'};
let obj8:object = [1, 2, 3];

// 非原始类型  object  Object  大小的区别


    let obj:{} = {name:"张三",age:50};
    let obj1:{name:string;age:number}
    obj=obj1;  //会报错  因为obj是空对象{}  

    //解决 1.把obj :后面的{} 去掉 
    //     2. 通过修改类型约束解决

    obj1=obj as { name: string; age: number };  通过修改类型约束解决

    let obj2:{} =2
	obj2=[]  //此时 这个对象的key是obj2 =后面跟着的才是value值  后面的覆盖前面的了

    //大写 Object 
    let obj3:Object=3;
	obj3={name:"",age:0};
	obj=[]    //没有问题 大写Object只是往里面存 

    //小写object
    let obj4:object;
    object=4;  //会报错  因为不了{}类型
	object={a:10,b:20}

    //总结 Object是object子类型

2、数组类型

    export {} // 导出 意思只在该模块区域有效

    let arr:Array=[1,2,3];
    let arr2:number[]=[10,20,30]   //这两者没有区别 意思是一样的 数组里面有number

//元组类型
    let arr3:[number,number]=[10,20];
	arr3.push(3);
    //	arr3[2]=2;  会报错 没有索引2的位置

//接口
    interface IArray {
    [key:number]:V ;  //如果是在数组里 key代码是索引  :V是数组里面的值
    }
    let arr4:IArray[number]=[10,20,30]

//type 类型别名 
    type ArrType={[key:number]:Object} //后面的Object相当于any 在Ts里面尽量不要给any
    let arr5:ArrType=[1,2,3,4,[],{}]  

3、字面量类型,联合类型,交叉类型

export {};
//字面量类型
    let num: "hello";
// num=2 不可以  num的类型就是"hello"  这个"hello"就是字面量类型

//解决 联合类型
    let str1:"hello" | number;
    str1=1;
    str1="hello";

//交叉类型 赋值前后两个类型都要满足
    let a:number & string ; //狗都不这样写

4、any&&unknown 类型

//any 什么类型都可以
    let a:any = 1;
	a="字符串"

// unknown也是可以放任何类型 只是限制这个类型的方法
    let b:unknown =1;
	b:"字符串"
	b.toFixed(2) //会报错 unknown 会进行类型检测   
//解决1
    if(typeof b =="number"){
        b.toFixed(2);
    }
//解决2
    (b as number).toFixed(2)

5、接口 interface

//接口 对象类型
    interface IObject {
        name:string;
        age:number;
    }
//重命名接口 不会覆盖 只会添加
    interface IObject {
        gender:string
    }
    let obj:IObject;
    	obj={
            name:"张三",
            age:10,
            gender:"蓝孩子"
        }


//数组类型
    interface IArr {
        [key:number]:string;  //[]里面的是索引  :跟着的是数据里面的值
    }
    let arr:IArr=["张三","李四"];

//函数类型
    interface FnItf {
        (name:string:age:number)=>void; //返回值是void 意思是空 什么都可以 不约束
    }
    let fn:FnItf=()=>{
        return "1"  //返回值不受影响
    }
//约束的形参必须有两个设置好的类型
    fn("张三",30)

6、接口类型

export {};
//接口类型  有两种(只读,可缺省)
interface NameItf {
    readonly name:string;  //只读 仅供读取 不可修改
}
interface AgeItf {
    age:number | undefined;
}
//接口类型 继承上面两个接口
interface PersonItf extends NameItf,AgeItf {
    //可缺省 可写 可不写
    height?:string;
}

let obj:PersonItf;
	obj={
        name:"",
        age:undefined
    }
//只读属性 仅供读取  不可修改
// obj.name="张三" 会报错

obj={
    name:"",
    age:123,
    height:""  //最后一个可写可不写
}

7、类型别名 type

//数据改名 或者
type NumType = number | string;
let a:NumType = 1;
	a="";

// 函数改名 void返回值是空 就是什么都可以
type FnType = ()=>void;
let fn:FnType;
fn=function(){};

//数组改名 [索引] 外面是组组的值
type ArrType ={[index:number]:NumType};
let arr:ArrType=[2,"张三"]

//对象改名 ?可写可不写
type Object ={name?:string;age?:number};
let obj:Object;
	obj={}

//类型别名不能重名 接口interface可以
type Object ={}  //会报错 重复使用

//接收interface不能够直接使用联合类型和交叉类型
interface  | NumType | FnType |Object  //会报错 不能使用联合类型 和交叉类型

//别名类型可以使用 
type newType = NumType | FnType | ArrType | Object | PersonItf  ;

8、函数类型

function fn(p1:number):void{}
function fn1(p1:number):string{
    return "我想返回就返回什么 因为没有约束"
}

//type别名 interface 都可以限定函数类型

//可选参数用的 一般可选参数放在后面 放在前面会报错
function fn2(p1:number,p2:string){}
fn2(1,"");
fn2(1)//会报错

//设置默认值
function fn3(p1:string = ""){}
fn3();

// ...arr接收剩余的参数 这个[]里面有number这个数据
function fn4(...arr:number[]){
    for(let i=0;i

9、this指向

function fn(){
    console.log(this)
}
fn();//指向外层作用域 this没有指向 都是继承过来的

//apply方法 和call方法 bind方法
fn.apply({name:"张三"},[1,2,3]) //apply方法  参数只能传[数据] 和字符串  立即调用
fn.call({name:"李四"},111) //什么都可以传 立即调用
fn.bind(a,10)() //需要自调用

//new操作符都做了什么
//new操作符的返回值  是看函数内的返回值决定的 如果返回的是对象 函数 就可以拿到这个对象  函数如果返回不是对象 函数哪么外面 拿到的是内部创建的对象

TypeScript二次深入熟悉

1、ts中的this指向

export {};
type ObjType = { myname: string };

// 将this指向ObjTyep 或Window  1、此时会报错 原因:当前作用域中没有window  需要在全局设置window属性
function person(this: ObjType | Window, myname: string) {
  this.myname = myname;
}

//3.调用Window时需要小写
window.person = person;
window.person("")//因为设置了调用这个函数时需要传入一个字符串

//4.
let obj:ObjType={
    myname:"张三"  
}

//5.使用person方法
person() // 会报错 因为this指向不是Object类型的变量  而ts中没有window 只有浏览器才有
//解决
person.call(obj,"123")

1.2、在全局设置 创建xxx. d.ts 文件

//设置一个接口  注意:设置接口时要首字母大写 使用的时候需要小写
interface Window {
    myname:string;
    person:(name:string)=>void
}

2、枚举 将数据设置默认值进行调用

export {}

//enum 枚举  将参数枚举成后台的返回值
enum StateCode {
    Success=200,
    TokenErr = 400,
    LoginErr=500
}

let res ={
    code : 0
}

//请求判断
if(res.code === StateCode.Success){
    //成功
}else if (res.code === StateCode.TokenErr) {
  // 失败
} else if (res.code === StateCode.LoginErr) {
  // 登录失效
}

js中的else if  真正的样子是 只是帮我们省略了{}号
 else{
     if{}
     else {
         if{}
     }
 }

3、泛型

泛型指的是类型参数化 即将原来某种具体的类型进行参数化 设计泛型的目的在于有效约束类型成员之间的关系 比如函数参数和返回值,类或者接口成员和方法之间的关系

export {};
// 泛型:类型参数化  E 是如果有传来的参数就设置 没有就设置默认的string
interface ArrItf {
  [index: number]: E;
}
//  前面的T是形参  V也是只不过V设置了默认值  后同的T|V是接收前面的参数
type NumAndStrAndBool = number | string | boolean | T | V;

let arr: ArrItf = [1, 2, 3];//传入了类型 所以是number[] 就是[里面有number]
let arr1: ArrItf = ['1', '2'];//没有传 默认是string[]
let arr2: ArrItf>=[12] // 自己看吧 联合类型太多


let res = {
  code: 0,
  data: [{ name: '' }],
  msg: '成功',
};

Promise.resolve(res).then((resurl)=>{
    console.log(resurl);
    if(resurl){}  //直接调用是允许的 因为Promise后面直接跟着成功的回调函数  是立即执行的
})

//类型约束
type DataType = { name: string }[];
type ResType = { code: number; data: D };
type PromiseType = Promise>;

function fnData():PromiseType{//通过泛型可以 .点出来数据
    return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve(res);
        }, 2000);
  });
}

fetchData().then((res) => {
  console.log(res);
  if (res.code) {//此时直接调用会报错 因为没有传参数类型 和上面的不一样  需要设置泛型
  }
});

4、class(类)

面向对象实践OOP编程思想 在实际工作中 都是极其有用的抽象 封装利器

export {};

calss Person {
    name:string;
    age:number;
    constructor(name:string,age:number){
        this.name=name;
        this.age=age
    }
}

let p = new Person("张三",18)
console.log(p.name,p.age,p.getName());

5、类的继承

使用extends 关键字实现继承 继承上面的Person

class Male extends Person {
    height: string;
    constructor({ name, age, height }: { name: string; age: number; height: string; }) {
        super(name, age); //通过super继承父类的方法和数据
        this.height=height
  }
}

let m = new Male({ name: "浩达", age: 50, height: "170" });
console.log(m.age, m.name, m.getName(), m.height);

m.getName()

6、类的修饰符(public、private、protected、readonly)

在TypeScript 中就支持3种访问修饰符 分别是public、private、protected。通过这三个修饰符做到控制属性和方法的访问。

  • public :基类 、子类、 类外部 都可以访问 默认是就是public

  • protected :基类 子类 可以访问 , 类外部不可以访问

  • private :基类可以访问 , 子类、类外部不可以访问

  • readonly: 只读属性 只可获取 不可修改

class Person {
    public readonly name: string = '张三';
    protected age: number = 20;
    private height: string = '180';
    protected getPersonInfo():void {
        console.log(this.name, this.age, this.height); // 基类里面三个修饰符都可以访问
    }
}

class Male extends Person {
    public getInfo():void {
        console.log(this.name, this.age); // 子类只能访问public、protected修饰符的
    }
}

let m = new Male();
console.log(m.name); // 类外部只能访问public修饰的
m.name = '李四'; // name属性使用只读修饰符,所以不能对name进行赋值修改操作

7、类的静态属性

基于静态属性的特性 往往会把与类相关的常量 不依赖实例this上下文的属性和方法定义为静态属性 从而避免数据冗余 进而提升运行性能

// 静态属性 static
class Person {
    static gender:string="蓝孩子"
}

//静态属性可以通过类名 去获取  不用再new了
console.log(Person.gender)

8、类抽象 (把数据和方法抽取)

抽象类 它是一种不能被实例化仅能被子类继承的特殊类

export {};
//abstract 抽象 
abstract class Person {
    abstract name:string;
    abstract getName():void;
    fn(){
        console.log("普通方法")
    }
}

new Person();// 会报错 不可以通过new创建抽象类的实例
//创建抽象类的方法
class Male extends Person {
    name!: string; // ! 变量初始化先不用赋值
    getName(): void {
    this.name = '张三';
    console.log(this.name);
  }
}

//抽出来之后  再使用new创建实例
let m = new Male();
m.getName();
console.log(m.name);
m.fn();

//也可以把抽象出来的实例 用作接口使用
let obj: Male;
obj = {
  name: '',
  fn() {},
  getName() {},
};

9、类的接口

接口 interface 也可以约束类的实现 使用接口与使用抽象类相比 区别在于接口 只能定义类成员的类型

export {};
// implements  是类接口的一种索引  必须要使用到这条索引才可以使用接口

interface PersonItf {
  height: string;
  getName: () => string;//这个函数的返回值是string
}

// 类实现接口 implements
class Person implements PersonItf {
  name: string = '张三';
  age: number = 0;
  height: string = '';
  getName(): string {
    return this.name;
  }
}

class Male implements PersonItf {
  height: string = '';
  getName(): string {
    return '';
  }
}

10、extends 工具类型

extends关键字判断泛型参数p是否string或者是number 其中的一种 最终类型的确定由三无运算的结果 决定

// extends判断前面的类型是否属于后面的类型
type TypeFn

= P extends string | number ? string[] : number; let m: TypeFn = 1; //如果不是直接返回一个number let m1: TypeFn = ['1', '2']; //是当前类型 就返回number[]

11、Required 设置必填

Required 可以设置必填 之前 设置的? 可填可不填 当设置了Required之后 就一定要填了 因为把 ? 删除了

export {};
interface PersonItf {
  name?: string; // ? 可填可不填
  age?: number;
  height: string;
}
let p1: PersonItf;
p1 = {
  height: "",//这里没有设置 所以可以不填
};

// Required 设置里面的属性都是必填的
type PersonType = Required;
let p2: PersonType;
// 现在约束的数据是必须要填的
p2 = {
  name: "",
  age: 0,
  height: "一米七",
};

12、类型推断 infer

类型推断 infer相当于声明一个变量接收传入的类型

// 类型推断:infer
// infer相当于声明一个变量接收传入的类型 自定义设置 
type TypeFn1

= P extends { name: infer N; age: infer A } ? [N, A] : boolean; let p: TypeFn1<{ name: string; age: number }> = ['', 0]; let p3: TypeFn1<{ height: string }> = false;

13、keyof

keyof 提取对象的属性名 、数组中的索引名、索引签名的类型

interface PersonItf {
  name: string;
  age: number;
  height: string;
  [index: number]: number;
}

type PersonType = keyof PersonItf; //把接口的属性名提取出来 'name' | 'age' | 'height' | number
let p: PersonType;
p = 'age';
p = 'name';
p = 'height';
p = 1;// 索引也可以提取 索引是number


interface FItf {
  [key: string]: string;
}
let p1: FItf;
p1 = {
  a: '1',
  b: '2',
  // c: 0,  会报错  value是string 
};
// 提取对象的属性 对象的key值 可以是string 也可以是number
type FType = keyof FItf; // string | number
let p2: FType;
p2 = '';
p2 = '123';
p2 = 1;

14、in 映射类型

type Required = { [P in keyof T]-?: T[P] };

  1. 我们只能在类型别名定义中使用 in,如果在接口(interface)中使用,则会提示一个错误

  2. in 和 keyof 也只能在类型别名定义中组合使用

interface PersonItf1 {
  // ['name']?: string; 在对象中可以这样获取   也可以obj.name  
  name: string;
  // [name]?: string; 但是不可以[name获取] 因为name是变量
  age?: number;
  height: string;
}


type PersonType1 = Required;// 通过Requirred 可以看到映射类型 

15、tyoeof 提取变量或者属性的类型

let str = ''; // string
type StrType = typeof str;
let s: StrType;
// s = 1; 报错 str是字符串属性
s = '1231223';

作者上班摸鱼被发现了,(入门学到这里基本是够的了)晚点再编写~~~

你可能感兴趣的:(typescript,javascript,前端)