typescript知识梳理

风浪子 风浪子     2022-09-04     448

关键词:

概述

 TypeScript简称TS,具有类型系统,且是JavaScript的超集。 它可以编译成普通的JavaScript代码。TypeScript支持任意浏览器,任意环境,任意系统并且是开源的。通过TS能够生成JS,TS是结构性语言,能够类似C#和Java那样,面向对象编程。可以采用VS或者VS Code作为编辑器。

基本类型

  布尔类型:let isDone: boolean = false;

  数字类型:let decLiteral: number = 6;//decLiteral: number =0xf00d;支持16进制、10进制

  字符串类型:let name: string = "bob";//可以使用模板,实例如let sentence: string = `Hello, my name is ${ name }`

  数组类型:let list: number[] = [1, 2, 3]; 或 let list: Array<number> = [1, 2, 3];

  元组类型:let x: [string, number]=["Hello",87];

  枚举类型:enum Color {Red = 1, Green, Blue};  let c: Color = Color.Green;

  任意值类型:let notSure: any = 4; notSure=‘Hello‘ ;

  空类型: let unusable: void = undefined;

接口(interface)

  TS中的接口不同于C#和Java有着明确的定义去规划继承接口的类。TS是结构性语言,更多的通过结构比对,来达到类型的兼容。

接口描述属性:

interface LabelledValue {
         label: string;
size?: number } function printLabel(labelledObj: LabelledValue) {
  if(labelledObj.size)
    console.log(‘尺寸:‘+labelledObj.size);   console.log(labelledObj.label); } let myObj
= {size: 10, label: "Size 10 Object"}; printLabel(myObj);

  我们在这里并不能像在其它语言里一样,说传给 printLabel 的对象实现了这个接口。我们只会去关注值的外形。 只要传入的对象满足上面提到的必要条件,那么它就是被允许的。还有一点值得提的是,类型检查器不会去检查属性的顺序,只要相应的属性存在并且类型也是对的就可以。size?:number标识该参数是可选类型,判断是否传入值可以通过if(lablelledObj.size)来确定;

接口描述函数:

  接口也可以描述函数类型。为了使用接口表示函数类型,我们需要给接口定义一个调用签名。 它就像是一个只有参数列表和返回值类型的函数定义。参数列表里的每个参数都需要名字和类型。函数的参数名不需要与接口里定义的名字相匹配。

interface SearchFunc { (source: string, subString: string): boolean; }
let mySearch: SearchFunc;
mySearch = function(source_T: string, subString_T: string) 
{   let result
= source.search(subString);   if (result == -1) {     return false;   }   else {     return true;   } }

接口描述类:

   类是具有两个类型的:静态部分的类型和实例的类型;


//**********************报错的代码部分******************************
//用构造器签名去定义一个接口并试图定义一个类去实现这个接口时会得到一个错误,因为当一个类实现了一个接口时,只对其实例部分进行类型检查。
//constructor存在于类的静态部分,所以不在检查的范围内 interface ClockConstructor {   new (hour: number, minute: number); } class Clock implements ClockConstructor {   currentTime: Date;   constructor(h: number, m: number) { } }

//*****************修改之后的代码部分********************************
//所以针对上面错误,我们将接口分为2部分,静态部分和实例部分接口。实例部分,我们采用继承来实现;直接操作静态部分 interface Clock
{ new (hour: number, Minute: number): ClockFun; } interface ClockFun
{ ShowData(): string; } class MyClock implements ClockFun { _hour: number; _minu: number; constructor(hour: number, Minu: number) { this._hour = hour; this._minu = Minu; } public ShowData(): string { return `当前时间:${this._hour}点${this._minu}分`; } } //静态部分的操作 function MyCeate2() { let datm: Clock = MyClock; let Namv2 = new datm(123, 5); Namv2.ShowData(); }
 

接口扩展:

  接口扩展包括接口之间的继承extends和接口继承类,接口继承了一个类类型时,它会继承类的成员但不包括其实现。 就好像接口声明了所有类中存在的成员,但并没有提供具体实现一样。 接口同样会继承到类的private和protected成员。

class OtherProClass{
  public height:numner;
}
interface
Shape {   color: string; } interface PenStroke {   penWidth: number; } interface Square extends Shape, PenStroke,OtherProClass {   sideLength: number; } let square = <Square>{}; square.color = "blue"; square.sideLength = 10; square.penWidth = 5.0;
square.height=100;

接口内容的混合使用:

  接口即可以标识字段、方法、签名方法、类,这些标识是可以混合定义在一个接口里面,由于TS中接口的含义广,所以命名是不建议用I开头,来标识一个接口含义;

interface Counter {
  (start: number): string;
  interval: number;
  reset(): void;
}
function getCounter(): Counter 
{   let counter
= <Counter>function (start: number) { };   counter.interval = 123;   counter.reset = function () { };   return counter; } let c = getCounter(); c(10); c.reset(); c.interval = 5.0;

联合类型

  联合类型表示一个值可以是几种类型之一。 我们用竖线( | )分隔每个类型,所以 number | string | boolean 表示一个值可以是 number , string ,或 boolean 。

 
interface Bird {
      fly();
      layEggs();
}
interface Fish {
      swim();
      layEggs();
}
function getSmallPet(): Fish | Bird {
    // ...
}
let pet = getSmallPet();
pet.layEggs(); // okay
pet.swim(); // errors
//为了让这码代码工作,我们要使用类型断言
let pet2 = getSmallPet();
if ((<Fish>pet).swim) {
   (<Fish>pet).swim();
}
else{
   (<Bird>pet).fly();
}

自定义的类型保护

  TypeScript里的类型保护机制让它成为了现实。 类型保护就是一些表达式,它们会在运行时检查以确保在某个作用域里的类型。 要定义一个类型保护,我们只要简单地定义一个函数,它的返回值是一个类型断言;

//pet is Fish 就是类型断言。一个断言是 parameterName is
Type 这种形式, parameterName 必须是来自于当前函数签名里的一个参数名
function isFish(pet: Fish | Bird): pet is Fish {
return (<Fish>pet).swim !== undefined;
}

//调用断言
if (isFish(pet) {
    pet.swim();
}
else {
    pet.fly();
}

  使用typeof 类型保护,来实现断言,这些 typeof 类型保护只有2个形式能被识别: typeof v ==="typename" 和 typeof v !== "typename" , "typename" 必须是 "number" , "string" , "boolean" 或 "symbol"

function isNumber(x: any): x is number 
{
return typeof x === "number"; }

    instanceof 类型保护,instanceof 类型保护是通过其构造函数来细化其类型。

 if (myDataNum instanceof MyClock)
 {
       console.log("输出数据类型");
 }

类型别名

  类型别名会给一个类型起个新名字。 类型别名有时和接口很像,但是可以作用于原始值,联合类型,元组以及其它任何你需要手写的类型。另一方面,如果你无法通过接口来描述一个类型并且需要使用联合类型或元组类型,这时通常会使用类型别名。

type XCoord = number;
type YCoord = number;
type XYCoord = { x: XCoord; y: YCoord };
type XYZCoord = { x: XCoord; y: YCoord; z: number };
type Coordinate = XCoord | XYCoord | XYZCoord;
type CoordList = Coordinate[];
let coord: CoordList = [{ x: 10, y: 10}, { x: 0, y: 42, z: 10 }]
type Container<T> = { value: T };//泛类型

类(Class)

  类是通用的代码块,我们在引用任何一个类成员的时候都用了 this 。 它表示我们访问的是类的成员。构造函数不同于C#和Java,采用 constructor来标识;类可以实现封装、继承和多态;子类可以重写父类的方法;在TypeScript里,每个成员默认为 public 的。

      当成员被标记成 private 时,它就不能在声明它的类的外部访问。TypeScript使用的是结构性类型系统。 当我们比较两种不同的类型时,并不在乎它们从哪儿来的,如果所有成员的类型都是兼容的,我们就认为它们的类型是兼容的。然而,当我们比较带有 private 或 protected 成员的类型的时候,情况就不同了。 如果其中一个类型里包含一个 private 成员,那么只有当另外一个类型中也存在这样一个 private 成, 并且它们是来自同一处声明时,我们才认为这两个类型是兼容的。 对于 protected 成员也使用这个规则。protected 修饰符与 private 修饰符的行为很相似,但有一点不同, protected 成员在派生类中仍然可以访问。

class Animal {
private name: string;
constructor(theName: string) { this.name = theName; }
}
class Rhino extends Animal {
constructor() { super("Rhino"); }
}
class Employee {
private name: string;
constructor(theName: string) { this.name = theName; }
}
let animal = new Animal("Goat");
let rhino = new Rhino();
let employee = new Employee("Bob");
animal = rhino;
animal = employee;//由于定义了Private成员,该出的成员定义不是出于同一处,所以赋值失败

属性参数

  通过构造函数里面,用protected、private和public修改参数,可以定义类属性;

class Animal {
  constructor(private name: string) { }
  move(distanceInMeters: number) {
    console.log(`${this.name} moved ${distanceInMeters}m.`);
  }
}

存取器

  TypeScript支持getters/setters来截取对对象成员的访问。 它能帮助你有效的控制对对象成员的访问。

class Employee {
  private _fullName: string;
  get fullName(): string {
    return this._fullName;
  }
  set fullName(newName: string) {
    if (passcode && passcode == "secret passcode") {
      this._fullName = newName;
     }
    else {
    console.log("Error: Unauthorized update of employee!");
      }
 }
}

  抽象类是供其它类继承的基类。 他们一般不会直接被实例化。 不同于接口,抽象类可以包含成员的实现细节。 abstract 关键字是用于定义抽象类和在抽象类内部定义抽象方法。类分为静态部分,用static修改,也分为实例部分;静态部分对象,可以直接通过类来访问;

class Greeter 
{
    static standardGreeting = "Hello, there";
    greeting: string;
    greet() {
        if (this.greeting) {
            return "Hello, " + this.greeting;
        }
        else {
            return Greeter.standardGreeting;
        }
    }
}
let greeter1: Greeter;
greeter1 = new Greeter();
console.log(greeter1.greet());
let greeterMaker: typeof Greeter = Greeter;
greeterMaker.standardGreeting = "Hey there!";
let greeter2:Greeter = new greeterMaker();
console.log(greeter2.greet());

命名空间和模块

  模块的引用

  import x from "..."; 或 import x = require("...") 里面的 ... ,等等)来定位模块的类型信息的。“内部模块”现在叫做“命名空间”。任何包含顶级 import 或者 export 的文件都被当成一个模块。

     导出声明:任何声明(比如变量,函数,类,类型别名或接口)都能够通过添加 export 关键字来导出。默认导出用default

//声明导出接口
export interface StringValidator {
isAcceptable(s: string): boolean;
}

//声明导出语句
class ZipCodeValidator implements StringValidator {
isAcceptable(s: string) {
return s.length === 5 && numberRegexp.test(s);
}
}
export { ZipCodeValidator };
export { ZipCodeValidator as mainValidator };

  导入:模块的导入操作与导出一样简单。 可以使用以下 import 形式之一来导入其它模块中的导出内容。

//可以对导入内容重命名
import { ZipCodeValidator as ZCV } from "./ZipCodeValidator";
let myValidator = new ZCV();

//将整个模块导入到一个变量,并通过它来访问模块的导出部分
import * as validator from "./ZipCodeValidator";
let myValidator = new validator.ZipCodeValidator();

  若要导入一个使用了 export = 的模块时,必须使用TypeScript提供的特定语法 import let = require("module") 。

参考博客

  1、TypeScript Handbook(中文版)

java知识树梳理

Java知识树梳理  1、前端    HTML    CSS    JavaScript  2、后台    Java基础     算法    web方面    分布式、中间件、服务器等方面    大数据方面  3、数据库 查看详情

java基础系列知识梳理

查看详情

html知识点梳理

HTML知识点梳理   第一周知识点总结1第二周知识点总结4第三周知识点总结5第四周知识点总结7第五周知识点总结10  第一周知识点总结HTML文档结构(括号里面的是注释)    <html><head>(头部部... 查看详情

javajavase知识梳理-集合

集合是静态数组的延伸列表和接口如下:  查看详情

网络知识梳理

背景学习网络知识参考https://blog.csdn.net/vcwanglailing/article/details/78911606 :浮动iphttps://blog.csdn.net/yjh314/article/details/52208236 :子网,网关 查看详情

网络知识梳理

背景学习网络知识参考https://blog.csdn.net/vcwanglailing/article/details/78911606 :浮动iphttps://blog.csdn.net/yjh314/article/details/52208236 :子网,网关 查看详情

mysql的知识梳理

数据准备:--建表createtablecustomer_jia(CIDint(4),Cnamevarchar(20),Csexvarchar(2),Cageint(3),Cjobvarchar(20),CCNOint(2));createtablecompan 查看详情

接口自动化知识梳理

接口自动化知识梳理学习知识块:基础知识类与对象单元测试requestsopenpyxlpandasreddtunittestmysqllogging框架梳理学习方式:靠时间堆思考清楚http请求类:写2组数据在Python里面。单元测试类:写2组数据在Python里面。解... 查看详情

kevinlearnreactnative-->reactnative知识梳理

ReactNative知识梳理【KevinLearnReactNative】–>组件的生命周期【KevinLearnReactNative】–>View组件【KevinLearnReactNative】–>Text组件【KevinLearnReactNative】–>开发工具—VSCode【KevinLearnReactNative】–&#x 查看详情

js知识体系的梳理一

今天简单的总结了js的一些东西,梳理下整个体系,每一次的总结都会有不同的收获;js总结一一、【获取元素】: 1、通过ID:varoBtn=document.getElementById(‘btn1‘); varoDiv=document.getElementById(‘div1‘); 2、通过标签:varaDiv=document.getElem... 查看详情

kevinlearnkotlin-->kotlin知识梳理

Kotlin知识梳理【KevinLearnKotlin】–>Kotlin学习资料【KevinLearnKotlin】–>数据类型【KevinLearnKotlin】–>数据容器(数组)【KevinLearnKotlin】–>数据容器(集合)【KevinLearnKotlin】–ÿ 查看详情

css知识梳理02

iframe在body里面嵌入一个页面属性:frameborder0/1是否显示边框scrollingyes/no/auto是否显示滚动条width/height设置框架的宽高 <frameset><frame/></frameset>1<iframeframeborder="0"scrolling="no"width="100%"height= 查看详情

kevinlearnjava-->java知识梳理

今天花时间整理了一下Java知识点,目前更新了33篇博文。为方便后面查阅。Java知识梳理【KevinLearnJava】–>编程规范(一)【KevinLearnJava】–>编程规范(二)【KevinLearnJava】–>编程规范(三&#... 查看详情

移动端知识梳理

插件:swiperiscrollejs(主要应用于node.js)zepto(同jq用法一样,更适合于移动端)lessH5:新增标签headerfootersectiontimemainnav...对于input新增表单元素属性,以及新增类型的优势emailtelurlsearchdatetimenumbercolorweekmonthrange(音量)->在移动端表单元... 查看详情

梳理知识

  总结一下自己今天记录和学到的知识一 vimware在win10的情况下怎么安装(1)首先先关闭防火墙以及杀毒软件。(2)试着安装14.1版本二怎么把eno改为eth(1)先用上下光标,止住sleet(60)(2)按住tab健(3)空格 net,ifna... 查看详情

jquery基础知识点梳理

DOM对象:直接使用JavaScript获取的节点对象:varobjDOM=document.getElementById("title");varobjHTML=objDOM.innerHTML;jQuery对象:使用jQuery包装DOM对象后产生的对象,它能够使用jQuery中的方法:$("#title").html();等同于document.getElementById("title") 查看详情

zip相关知识梳理(代码片段)

zip相关知识梳理(一)经过对zip文件的长时间研究,对zip文件进行相关知识进行梳理,虽然网上很多牛人对其做了相关基础解析,但是对于特殊情况没有进行说明,比如超过4G的zip文件该以什么格式进行编译,现本人对其进行详细... 查看详情

知识梳理

1、一个.java文件至多有一个public方法:classT{privateinti;intj;protectedintk;publicintL;}/*1、一个.java文件只允许出现一个publicclass,且用public修饰的类名作为文件名2、该文件名为Test.java,程序主类可用public修饰,也可以不用如果是给外部... 查看详情