typescript基础学习

1.typescript类型
let num1:number = 213;
let str1:string = '222';
let bool1:boolean = true;
// 数组和元祖
let arr:string[] = ['dwadw']; // 字符串类型的数组
let arr1:Array<string> = ['dwadw']; // 字符串类型的数组
let arr2:(number | string)[] = ['dwadwad',21231]; // 联合类型(多种类型的数组,可以写联合类型里的类型,可以写多个)
let arr3:any[] = ['wdawda',2123,232,undefined,null]; // 任意类型的数组
let arr100:[string,number,boolean] = ['dwadw',21231,true]; // 元祖,元祖就是知道类型,知道个数的数组
// 枚举类型:ts枚举类型的取值,默认是从上到下,从0开始递增的,也可以手动更改默认值
//          如果手动调了后面的默认的值,那么前面的值不会发生改变。就算你把第二个设置为0,第一个也是0,但是你根据索引[0]获取数据只能获取到第二个
//          我们可以通过枚举拿到对应的数字,还可以通过对应的数字拿到对应的枚举值
//          ts中的枚举底层实现的本质其实是数据类型,所以赋值一个数值不会报错
enum Gender{
    Male,
    Femal
}
enum MyGender{
    Male = 1,
    Femal
}
enum MyGender1{
    Male,
    Femal = 0
}
console.log(MyGender1); // { '0': 'Femal', Male: 0, Femal: 0 }
console.log(MyGender.Male,'male');  // 1
console.log(MyGender.Femal);  // 2
let sex:Gender = Gender.Male;
console.log(sex); // 0

enum sexList{
    man,
    woman
}
let sex1:sexList = sexList.man;
let sex2:sexList = sexList.woman;
console.log(sex1); // 0
console.log(sex2); // 1
let sex3:sexList;
sex3 = sexList.woman;
sex3 = 5; // ts中的枚举底层实现的本质其实是数据类型,所以赋值一个数值不会报错
2.any与void null与undefined
// any和void类型
// any表示任意的类型当不清楚某个值的类型的时候就可以用any
// 一般用于定义通用性比较强的变量,获取保存其他框架中获取到的不确定类型的值
let any1:any;
any1 = 'dwad';
any1 = 2123;
any1 = ['dwadw',2132,21321];

// void类型表示没有任何类型,一般用于函数的返回值,如果函数里没有return 任何东西就用void来表示,打印不算返回
//          如果一个变量定义为void类型,严格模式下只能保存undefined,关闭严格模式可以保存 null和undefined
//          保存string,number,boolean,array,

// null和undefined表示是所有类型的子类型,所以我们可以将null和undefined赋值给任意类型
function test1():void{
    console.log('2222');
    return undefined;
}
test1(); // 2222
let value:void; // 定义了不可以保存任何类型的变量,严格模式下只能保存undefined,关闭严格模式可以保存 null和undefined
// value = null;
value = undefined;
3.never类型
// 表示的是那些用不存在的值的类型
// 一般用于抛出异常或根本不可能返回值的函数
function demo():never{
    throw new Error('baocuole');
}
demo();

function demo2():never{
    while(true){
        console.log('222');
    }
}
demo2();
4.object类型
// object表示一个对象
let obj1:object; // 定义了一个只能保存变量的对象
obj1 = 1; // 报错
obj1 = '222';// 报错
obj1 = true;// 报错
obj1 = {
    name:'2',
    age:222
}
5.类型断言
// 类型断言:
//          什么是类型断言?类型断言就是和类型转换一样,可以将一种类型强制转换为另一种类型
//          类型断言就是告诉编译器,你不用帮我检查了,我知道自己要干什么
//          假如:我们拿到了一个any类型的变量,但是我们明确知道这个变量保存的是字符串,此时我们可以通过类型断言,告诉编译器,这个变量是一个字符串
let str:any = 'laotianwy';
console.log(str.length); // .length是手打的,没有提示
// 方式一:<string>变量
// <string>str.length
console.log((<string>str).length); // 此时有提示
// 方式二:变量 as 类型     (推荐as)
// (str as string).length;
console.log((str as string).length); // 有提示
6.ts变量的声明和结构赋值
// TS中变量声明和解构
// 具体查看:JavaScript变量定义-ES6
// 具体查看:JavaScript-变量作用域-ES6
// 具体查看:JavaScript-函数扩展运算符-ES6
// 具体查看:JavaScript-对象解构赋值-ES6
7.接口
// interface? 接口
//          和number,string,boolean,enum这些数据类型一样,接口也是一种类型,也是用来约束数据的
// 定义一个接口
interface fullname{
    firstname:string
    lastname:string
}
let obj = {
    firstname:'111',
    lastname:'222',
    fullname:'333'
}

// 需求: 要求定义一个函数输出一个人完整的姓名, 这个人的姓必须是字符串, 这个人的名也必须是一个字符
function say({firstname,lastname}:fullname):void{
    console.log('我的名字是'+firstname+'_'+lastname);
}

say({firstname:'111',lastname:'222'}); // true 如果在实参传递的是一个值,而不是一个变量,那么就不能多也不能少
say({firstname:'111',lastname:'222',fullname:'333'});// 报错
say(obj); // 如果传递的是一个变量,可以进行多,但是不能少
8.接口参数多了或者少了怎么办
// 定义一个接口:如果使用接口来限定了变量或者形参, 赋予的值就必须和接口限定的一模一样才可以, 多一个或者少一个都不行。
//  少了该怎么办呢?就出现了可选属性
//  可选属性:在定义接口的时候,属性的后面添加 ? 就可以了
interface FullNmaeList {
    firstname:string
    lastname:string
    middlename?:string
}
function say({firstname,lastname,middlename}:FullNmaeList):void{
    if(middlename){
        console.log(`我的名字是三个字${firstname}_${lastname}:${middlename}`)
    }else{
        console.log(`我的名字是两个${firstname}${lastname}`)
    }
}
say({firstname:'111',lastname:'222',middlename:'3333'}); // 我的名字是三个字111_222:3333
let obj = {firstname:'111',lastname:'222'}; 
say({firstname:'111',lastname:'222'}); // 我的名字是两个111222
say(obj); // 我的名字是两个111222

//  多了该怎么办?
//  方式一:使用类型断言:as
//  方式二:使用变量
//  方式三:使用索引签名:在interface里面设置[propsname:string]:any
//  需求: 如果传递了middleName就输出完整名称, 如果没有传递middleName, 那么就输出firstName和lastName

interface FullMoreInterface{
    firstname:string
    middlename:string
    lastname:string
}
function say1({firstname,middlename,lastname}:FullMoreInterface):void{
    console.log(`my_name_is_${firstname}_${middlename}_${lastname}`);
}
say1({firstname:'111',middlename:'222',lastname:'333',aaa:'444'} as FullMoreInterface); // 通过as
let obj1 = {firstname:'111',middlename:'222',lastname:'333',aaa:'444'};
say1(obj1); // 通过变量
// 通信设置设置interface
interface FullMoreInterface1{
    firstname:string
    middlename:string
    lastname:string
    [propsname:string]:any
}
function say2({firstname,middlename,lastname}:FullMoreInterface1):void{
    console.log(`my_name_is_${firstname}_${middlename}_${lastname}`);
}
say2({firstname:'111',middlename:'222',lastname:'333',aaa:'444'}); // 不会报错
9.索引签名
// 什么是索引签名?
//      索引签名用于描述那些-'通过索引得到'的类型,比如arr[10]或者obj[key]
interface Fullname{
    [propsname:string]:string
}
let obj1:Fullname = {
    firstname:'laotian',
    lastname:'tian',
    age:'22',
    // middlename:false // 报错
    false:'666' // 无论key是什么类型最终都会被转换为字符串,所以没有报错
}

interface ArrayNumber{
    [propsname:number]:string
}

let obj2:ArrayNumber = {0:'a',1:'b',2:'c'};
let arr1:ArrayNumber = ['dwad','dw','dwadw'];
console.log(obj2[0]); // a
console.log(arr1[0]); // dwad
10.只读属性和只读数组
// 什么是只读属性
//      让对象属性只能在对象刚刚创建的时候修改其值
interface Fullname1{
    firstname:string
    readonly lastname:string
}
let myname:Fullname1 = {
    firstname:'laotian',
    lastname:'ixao'
}
// myname.firstname = 'firstname'; // 正常
// myname.lastname = 'dwadwa'; // 报错

let myname1:Fullname1;
// myname1.firstname = 'dwadwa'; // 报错,只能整个赋值,不能单个属性赋值
myname1 = {
    firstname:'xiaotian',
    lastname:'dwadw'
}

//  只读数组
//          ts内部对只读属性进行了扩展
let arr:string[] = ['a','b','c'];
let arr1:ReadonlyArray<string> = ['dwad','dwa','dwad','d'];
arr1[0] = 'dwadw'; //报错
arr[0] = 'dadwad';
console.log(arr1[0]);
console.log(arr[0]);
11.函数接口与混合类型接口
//  函数接口
//          我们除了可以通过接口来限定对象以外,还可以通过接口来限制函数
interface FuncInterface{
    (a:number,b:number):number
}
let fun1:FuncInterface = function(a:number,b:number):number{
    return a+b;
}
let res = fun1(11,22);// 33

//  混合类型接口
//          约定的类型既有对象属性,又有函数
//          要求定义一个函数实现变量累加
let count = 0; // 会污染全局变量
function demo(){
    count++;
    console.log(count);
}
demo(); // 1
demo(); // 2
demo(); // 3

// 使用闭包,解决污染全局变量的问题
let demo1 = (() => {
    let count = 0;
    return () => {
        count++;
        console.log(count);
    }
})();
demo1(); // 1
demo1(); // 2
demo1(); // 3

interface ObjAndFunc{
    ():void
    count:number
}
let getCount = (function():ObjAndFunc{
    //接口要求数据既要是一个没有参数没有返回值的函数,又要是一个拥有count属性的对象,fn作为函数的时候符合接口中函数接口的限定 ():void,fn作为对象的时候符合接口中对象属性的限定  count:number
    let fn = <ObjAndFunc>function(){
        fn.count++;
        console.log(fn.count);
    };
    fn.count = 0;
    return fn;
})();
getCount();// 1
getCount();// 2
getCount();// 3
getCount();// 4
12接口的继承
//  接口的继承
//          ts中接口和js的类一样是可以继承的
interface LengthFace{
    length:number
}
interface WidthFace{
    width:number
}
interface HeightFace{
    height:number
}

interface CalcFace extends LengthFace,WidthFace,HeightFace{
    color:string
}
// 如果实现这个继承的接口,那么必须要全部实现
let rect:CalcFace = {
    length:10,
    width:22,
    height:100,
    color:'#fff'
}
13ts中的函数
// ts中的函数
// ts中的函数大部分和js相同

// 命名函数
function add(){}
// 匿名函数
let add1 = function(){}
// 箭头函数
let add2 = () => {}

// 命名函数
function test(name:string):void{
    console.log(name);
}
// 匿名函数
let test1 = function(name:string):void{
    console.log(name);
}
// 箭头函数
let test2 = (name:string):void{
    console.log(name);
}
14ts函数的完整格式
//  ts函数的完整格式
//  在ts中函数的完整格式由函数的定义和实现,两个部分组成

// 1.定义一个函数
let add:(a:number,b:number) => number;
// 2.根据定义实现函数
add = function(a:number,b:number):number{
    return a+b;
}
let res = add(10,20);
console.log(res); // 30

// 一步到位的写法
let add1:(a:number,b:number) => number = function(a:number,b:number):number{
    return a+b;
}
console.log(add1(10,50)); // 60

// 根据函数的定义自动推导对应的数据类型
let add2:(x:number,y:number) => number = function(x,y){
    return x+y;
}
let add3:(x:number,y:number) => number = (a,b) => {
    return a+b;
}
15.type声明函数类型
// type声明函数类型
type addFunc = (a:number,b:number) => number;
// 完整写法
let add0:addFunc = function(a:number,b:number):number{
    return a+b;
}
// 简便写法
let add:addFunc = function(a,b){
    return a+b;
}
16.函数的重载
// 函数的重载:就是同名的函数根据不同的参数实现不同的功能,函数的重载只能定义,不可在定义的时候实现
/* 当前报错
function GetArr(x:number):number[]{
    let arr = [];
    for(let i=0;i<x;i++){
        arr.push(i);
    }
    return arr;
}
function GetArr(s:string):string[]{
    return s.split('');
}*/


function GetArr(x:number):number[];
function GetArr(s:string):string[];
function GetArr(a:any):any[]{
    if(typeof a === 'string'){
        return a.split('');
    }else{
        let arr = [];
        for(let i=0;i<a;i++){
            arr.push(i);
        }
        return arr;
    }
};
console.log(GetArr('2222')) // [ '2', '2', '2', '2' ]
console.log(GetArr(9)); // [0, 1, 2, 3, 4,5, 6, 7, 8]
17.函数的可选参数与函数的扩展运算符
//  函数的可选参数
//  需求: 要求定义一个函数可以实现2个数或者3个数的加法.
//  1.可选参数 注意:可选参数后面只能跟可选参数,可选参数可以是一个或者多个
function add(x:number,y:number,z?:number):number{
    // if(z){
    //     return x+y+z;
    // }else{
    //     return x+y
    // }
    return  x+y+(z ? z:0);
}
console.log(add(2,1)); // 3
console.log(add(2,2,2)); // 6

// 可选参数可以配合函数的重载一起使用,这样可以让函数重载变得强大
function add1(x:number,y:number):number;
function add1(x:number,y:number,z:number):number;
// 实现add1的所有重载
function add1(x:number,y:number,z?:number){
    return x+y+(z ? z:0);
}
console.log(add1(10,20,30),'add1'); // 60 add1
// 可选参数后面只能跟可选参数,可选参数可以是一个或者多个
function props(x:number,y?:number,z?:number){
    return x+(y ? y:0)+(z ? z:0);
}
console.log(props(1)); // 1

// 函数的扩展运算符
function propstaion(x:number,...arg:number[]){
    console.log(x,'x'); // 2 x
    console.log(arg,'arg'); // [123,21,3,21,3,21,32,1,3,21,32] arg
}
console.log(propstaion(2,123,21,3,21,3,21,32,1,3,21,32));
18泛型
//  什么是泛型
//  在编写代码的时候我们既要考虑代码的健壮性, 又要考虑代码的灵活性和可重用性
//  通过TS的静态检测能让我们编写的代码变得更加健壮, 但是在变得健壮的同时却丢失了灵活性和可重用性
//  所以为了解决这个问题TS推出了泛型的概念
//  通过泛型不仅可以让我们的代码变得更加健壮, 还能让我们的代码在变得健壮的同时保持灵活性和可重用性
//  需求: 定义一个创建数组的方法, 可以创建出指定长度的数组, 并且可以用任意指定的内容填充这个数组
let getArr = (value:number,items:number = 9):number[] => {
    return new Array(items).fill(value); // items是几个,fill是用什么填满
}
// console.log(getArr(6,3)); // [6,6,6]
// console.log(getArr('list')); // 报错

// 1.用any 解决即用number又用string,不会报错数字没有length,而且item没有length属性这个是手打的
let getArr1 = (value:any,items:number = 10):any[] => {
    return new Array(items).fill(value);
}
console.log(getArr1(10,4).map(item => item.length)); // 不会报错数字没有length,而且item没有length属性这个是手打的
// console.log(getArr1(10,4)); // [ 10, 10, 10, 10 ]
// console.log(getArr1('www',4)); // [ 'www', 'www', 'www', 'www' ]

// 2.使用泛型
let getArr2 = <T>(value:T,items:number = 5):T[] => {
    return new Array(items).fill(value);
}
console.log(getArr2('2222222')); // [ '2222222', '2222222', '2222222', '2222222', '2222222' ]
console.log(getArr2(1111111)); // [ 1111111, 1111111, 1111111, 1111111, 1111111 ]
console.log(getArr2('2222222').map(itme => itme.length));
console.log(getArr2(1111111).map(item => item.toFixed(2)));
19泛型约束
// 泛型约束:用接口进行约束泛型
// 默认情况下,可以指定泛型为任意类型
// 但是有些情况下,我们需要指定的类型满足条件后才能指定
// 这样我们就可以用到泛型约束
// 需求: 要求指定的泛型类型必须有Length属性才可以
interface LengthPropsFace{
    length:number
}
let getArray = <T extends LengthPropsFace>(value:T,items:number = 5):T[]=> { // T这个类型必须要有接口里的length属性
    return new Array(items).fill(value);
}
let arr = getArray<string>('abc');
// let arr1 = getArray<string>(22222); // 报错 类型“number”不满足约束“LengthPropsFace”。
20.泛型约束中使用类型参数
// 在泛型约束中使用类型参数
// 一个泛型被另一个泛型进行约束,叫做:泛型约束中使用类型参数
// 需求: 定义一个函数用于根据指定的key获取对象的value
let getProps = <t,k extends keyof t>(obj:t,keys:k):any => { //k必须依赖于t并且是t的键
    return obj[keys];
}
let obj = {
    a:'a',
    b:'b',
    c:'c'
}
// getProps(obj,'e'); // 类型“"e"”的参数不能赋给类型“"a" | "b" | "c"”的参数。ts(2345)
getProps(obj,'a'); // a
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值