• typescript相关知识点总结


    本文讲解typescript语法

    由于js语法本身的混乱,再加上目前框架的割据,导致typescript用起来没有一致性,本文尽量总结实际开发中可能会用到的知识点

    目录

    数据类型
    类型断言
    duck typing
    函数类型的验证
    索引验证
    类验证
    接口扩展
    泛型
    与第三方库一起使用
    命名空间
    react组件属性验证


    1. 数据类型

      Boolean 布尔类型 let isDone: boolean = false;
      Number 数字类型 let num: number = 5;
      String 字符串类型 let str: string = 'aa';
      Array 数组 
          let list: number[] = [1, 2, 3];
          let list: Array<nubmber> = [1, 2, 3];
          let list: [string, number] = ['aa', 11];
          let arr: ReadonlyArray<number> = [1, 2, 3]; // 只读数组
      Enum 枚举类型,是typescript对javascript语法的扩展类型
          枚举类型用来将一组无意义的数值转变成识别度高的属性
          enum Color {Red, Green, Blue} // 声明枚举
          let a: Color = Color.Grean // 1
          let a: string = Color[2]; // Blue
          枚举值,默认从0开始递增,可以手动赋值
      Any 类型,是typescript自己扩展的类型
          any类型的作用就是用来暂时关闭类型验证,对此变量不做任何类型的验证,我不推荐用这个类型,建议Object代替
          let a: any = 1; 
      Object 类型,是typescript自己扩展的类型
          Object类型的作用,是表示此变量可以为任意类型的值
          let a: Object = 1;
      Void 类型,是typescript自己扩展的类型
          Void 类型,主要用来表示没有返回值的函数
          function a(): void {}
      Null 和 Undefined 类型
          顾名思义,表示一个变量专门用来表示 Null 或者 Undefined
          let a: undefined = undefined;
          let a: null = null;
      Never 类型
          用来表示报错的函数,或者死循环的函数
          function fn() :never { throw new Error("aaa"); }
          function fn (): never { while(true) {} }
      
    2. 类型断言

      字面意思‘断言’,即人为决定类型,不需要typescript自动侦测
      两种语法
          尖括号语法,不推荐,此法react不支持
              let str: Object = "aaa";
              let strLength: number = (<string>someValue).length;
          as语法,推荐此语法,并且c#内部也推荐此语法
              let str: Object = 111;
              let num: Number = str as Number;
      
    3. duck typing

      duck typing是任何一门面相对象语言都有的类型验证方式,说简单点,就是一次验证多个变量
      宽松的duck typing,只要变量需要验证的参数存在于传递的参数里面即可
          对象写法
              function fn(obj: {a: string}) {}
              let obj = {a: "aa", b: 1};
              fn(obj);
          interface写法
              interface params {
                  a: string
              }
              function fn(obj: params) {}
              let obj = {a: "aa", b: 1};
              fn(obj);
          可选的参数
              对象写法 
                  function fn(obj: {a?: string}) {}
              interface写法  
                  interface params {
                      a?: string
                  }
                  function fn(obj: params) {}
          只读的参数
              对象写法
                  {readonly a: string}
              interface写法
                  interface params {
                      readonly a: string
                  }
      严格的duck typing,传递的参数和验证的参数必须完全一致
          interface params {
              a: string
          }
          function fn(obj: params) {}
          fn({a: "aa"});
          这种模式下可选参数已经失去了意义,为了挽救可选参数,解决方法有如下两种
              as语法
                  interface params {
                      a?: string,
                      b?: number
                  }
                  function fn (obj: params): void {}
                  fn({b: 11, c: "bb"} as params);
              索引签名 
                  interface params {
                      a?: string,
                      b?: number,
                      [propName: string]: any
                  }
                  function fn (obj: params): void {}
                  fn({b: 11, c: "bb", d: true});  
      
    4. 函数类型的验证

      函数的验证使用接口来实现会更加的简洁
      interface myFn {
          (a: string, b: number): void
      }
      let fn: myFn = function(name, age){};
      fn("aa", 11);
      在定义函数时,函数的参数可以写类型也可以不写,并且参数的名称和接口的参数名称不需要相同
      注意:在javascript中,函数其实就是一个对象,所以函数的验证可以存在即是对象又是函数的情况,如下
          interface Test {
              (a: string): string;
              b: number;
          }
          function Fn() : Test {
              let fn = function(a: string){return a} as Test;
              fn.b = 111;
              return fn;
          }
      函数验证的其他写法
          let fn: (a: number) => void = function(x: number): void { }
          let fn = function(x: number): void { }
          let fn: (a: number) => void = function(x){ }
          let fn: (a?: number) => void = function(x){ } 可选参数
          function fn(a: string | number){ } 多种参数类型
      
    5. 索引验证

      只要可以通过索引访问成员的数据类型,在typescript中都可以使用索引验证
      众所周知,索引可以是字符串和数值,但是在js中,数值的索引等价于字符串的索引,
      也就是说在typescript中,将索引指定为数值类型等价于字符串类型
      interface Entries {
          [index: number]: number;
      }
      let arr: Entries = [1, 2, 3];
      同样还支持只读的索引
          interface ReadonlyStringArray {
              readonly [index: number]: string;
          }
      
    6. 类验证

      用接口验证类只能验证类的实例属性,构造函数这类的非实例属性无法验证
      interface Test {
          a: string;
          fn(b: number): void;
      }
      class Demo extends React.Component implements Test  {
          a: "aa"
          fn = (b: number) => { }
      }
      typescript对es6的类做了进一步的扩展,使其支持访问修饰符,抽象类抽象方法
          访问修饰符
              Public 默认,公开成员
              private 只能在类内部访问
              protected 本类内部和子类内部可以使用
              Readonly 只读属性
              static 静态属性 
          抽象类,作用和接口类似,主要用来给其他类提供公共成员
              抽象类无法实例化,抽象方法只能提供定义,在子类中必须实现
              abstract class Demo {
                  a: string;
                  fn():void { console.log("aa"); }
                  constructor(a: string) {this.a = a};
                  abstract Fn(): void;
              }
              class Test extends Demo {
                  constructor(){
                      super("aaaaaa");
                  }
                  Fn():void {
                      console.log("bbb");
                  }
              }
      
    7. 接口扩展

      接口可以继承其他接口
          interface Test1 {
              a: string;
          }
          interface Test2 {
              b: string;
          }
          interface Test3 extends Test1, Test2 { }
      接口继承其他类
          class Demo {
              public a: string;
              private b: number;
              protected c: string;
          }
          interface Test extends Demo {}
          class Demo1 extends Demo implements Test{
              public a: "aa";
          }
          注意,由于接口继承类,接口可以继承类的private和protected成员,所以子类继承此接口要同时继承父类才行
      
    8. 泛型

      泛型也是一个非常简单的东西,就是类型参数
          泛型函数
              function fn<T>(params: T): T {
                  return params;
              }
              fn<string>('aa'); 显示调用
              fn('aa'); 隐式调用
              完整写法
                  let fn: <T>(params: T) => T = function<T>(params: T): T {
                      return params;
                  };
          泛型接口
              不提取参数
                  interface Itf {
                      <T>(params: T): T;
                  }
                  let fn: Itf = function<T>(params: T): T {
                      return params;
                  };
              提取参数
                  interface Itf<T> {
                      <T>(params: T): T;
                  }
                  let fn: Itf<string> = function<T>(params: T): T {
                      return params;
                  };
          泛型类
              class Demo<T>{
                  fn: (a: T) => T;
              }
      泛型约束
          没有泛型约束,泛型将毫无用处,泛型参数默认是个白板儿,啥都没有
          一般写法
              interface Demo {
                  length: number;
              }
              function fn<T extends Demo>(str: T): T {
                  window.console.log(str.length);
                  return str;
              }
              fn('aa');
          相互约束
              function fn<T, K extends keyof T>(obj: T, key: K) {
                  window.console.log(obj[key]);
                  return obj[key];
              }
              fn({a: 1}, 'a');
          验证类的构造函数
              class Test {
                  constructor(){}
              }
              function fn<T>(obj: {new(): T}): T{
                  return new obj();
              }
              fn(Test);
      
    9. 与第三方库一起使用

      很多基于npm的第三方包,都没有使用typescript,那么在ts中想使用这些安装包,需要遵从如下操作
      第一,在项目中新建一个.d.ts文件,如 third.d.ts 
      第二,在文件中定义模块,如
          declare module "url" { // 此模块名必须和第三方包的名字一样
              export interface Url {
                  protocol?: string;
                  hostname?: string;
                  pathname?: string;
              }
              export function parse(urlStr: string, parseQueryString?, slashesDenoteHost?): Url;
          }
          declare module "path" {
              export function normalize(p: string): string;
              export function join(...paths: any[]): string;
              export var sep: string;
          }
          declare module "hot-new-module"; 不想写声明可以不写
      第三,在需要使用第三方包的文件中导入模块
          /// <reference path="third.d.ts"/> 导入.d.ts声明文件
          import * as URL from "url"; 导入模块
          let myUrl = URL.parse("http://www.typescriptlang.org");
      
    10. 命名空间

      命名空间和js的对象一样,单纯的为了避免命名冲突
      namespace Demo {
          export let a = 'aa';
      }
      window.console.log(Demo.a);
      
    11. react组件属性验证

      使用React typings注入
          interface Props {
              a: string;
          }
          class App extends React.Component<Props, {}> {
              render() {
                  return (
                  <div className="App">
                      {this.props.a}
                  </div>
                  );
              }
          }
      使用此组件
          <App a="aa"/>
      
  • 相关阅读:
    [微软认证]MCP问题解答
    邮件服务
    QueryString 整站过滤
    今天开始安卓的底层开发吧。
    所谓的回调函数
    UTF8 to unicode
    TCP/IP中的拥塞窗口控制机制
    (转)前端页面,页内锚定位分析
    远程连接Sql Server 2008 R2 命名实例
    字符编码研究
  • 原文地址:https://www.cnblogs.com/ye-hcj/p/8367215.html
Copyright © 2020-2023  润新知