TypeScript | 青训营笔记

28 阅读4分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 2 天

TypeScript

一、为什么使用TypeScript

ts能让前端库项目开发变的更简单。

使用js编程的时候,有一种让人很纠结的情况,就是程序运行错误是上层传入参数错误导致的,不管是直接还是间接。

使用传统js写库,对这种情况其实是很纠结的。我们都希望库的导出接口能健壮一些,错误信息明确一些,那怎么办呢?要么本来可以返回void的接口,凭空多出了返回值,要么就抛异常。我个人觉得抛异常更合理,你总不能为了排错方便,就劣化本来设计的很好的接口签名。但是这一点也有争议,我同事专门批评过我这一点,他的看法是底层代码尽量不要抛异常,因为测试用例可能覆盖不到你抛异常的情况,导致线上隐患。

总而言之吧,你如果不希望错误参数传染到你内部的逻辑流程,你在接口里就要写一大堆检查代码,如果让程序员自己写,就会五花八门,如果使用系统性解决方案,比如JOI,工作量说实话也不小,性能也不会很好。而且最终还是解决不了我同事说的那个问题——运行时报错很难被测试用例完全覆盖,还是会导致线上隐患。

二、TypeScript基本类型

1、字符串类型

var text:string = 'hello world';
  console.log('字符串:',text);
  

2、数字类型

 var number:number = 1;
  console.log("数字:",number);
  

3、布尔类型

 var bool:boolean = false;
  console.log("布尔:",bool);
  

4、数组类型

     // 1-数字数组
      var array:number[] = [1,2,3];
      console.log("数组1:",array);
      

要注意:function test() {console.log(arguments);}中arguments在typescript中默认为数字数组,但是却不能使用数字数组的方法

      // 2-泛型
      var arr:Array<number> = [1,2,3]
      console.log("数组2:",arr);
      // 3-元组tuple
      var arrays:[string,number] = ['hello',6];
      console.log("元组:",arrays);
      // 4-不确定类型数组
      var arraylist: any[] = ['hello','world',123] ;
      console.log('不确定数组:',arraylist);
      

5、any类型

不建议使用,因为any类型ts无法审查错误

  var notsure:any = 'handsome';
  console.log('any:',notsure);
  

6、unitype 联合类型

  var numberOrString:number|string|boolean = 123;
  numberOrString = '123';
  numberOrString = false;
  

注意:联合类型中右侧值只能为左侧列举出的类型,否则会引起报错

7、interface接口类型

   interface Person {
    name:string;
    age:number;
    gender?:string;
    // 加问号表示可选属性
    readonly id: number;
    // readonly的值不能重新赋值,与const差不多
  }
  

readonlyconst 用法差不多,只不过readonly只能使用在interface中,const只能使用在函数中

如果定义一个类kb,类型为Person,那么kb中需要包含Person中所有必选属性

   let Kb: Person = {
    name: 'kb',
    age: 19,
    id: 1
  }

8、类型别名

可以用type定义变量为一个类型的别名,可以使代码更清晰,可读性更高,例如下面声明PlusType为sum这一类的类型别名

  type PlusType = (x:number,y:number) => number 
  function sum(x:number,y:number) :number {
    return x+y;
  }
  const sum2 :PlusType = sum;
  

9、generics泛型

泛型是指在声明时不指定变量类型,使用时才进行定义的变量类型

下面例子的echo函数就使用了泛型,echo括号中的值可以为任意类型,但是echoWithArray()函数中调用了arg的length方法,所以只有数组和字符串类型可以被添加进去。

   function echo<T>(e: T) :T {
        return e;
    }
    const result = echo('string');
    
    function echoWithArray<T>(arg:T[]) :T[] {
        console.log(arg.length);
        return arg;
    }
 

可以使用约束泛型,使echoWithArray()函数的复用性增强

   interface IWithLength {
        length:number;

    }

    function echoWithLength<T extends IWithLength>(arg:T) :T {
        console.log(arg.length);
        return arg;
    }
    

通过继承的方式,使泛型继承了IWithLength的length方法,这样,不仅只有array和string类型可以被填入,其他类型的数据也会因有length方法而合法

10、partial类型

partial可以说很好的解决了interface的实例中,每一次修改都要包含所有内容的问题,虽然不用partial也可以解决(将所有内容前都打上'?'),但显然不如partial方便

   interface Blog { 
       id: string; 
       title: string; 
       slug: string; 
       categories: string[]; 
       tags: string[]; 
       featureImageUrl?: string; 
       content: string; 
   } 
   const draft: Partial<Blog> = { title: 'title' }