typescript


1,什么是typescript?
官方定义ts是js的超集,反之js就是ts的子集;所以ts包含很多js没有的能力,弥补了js弱类型的不方便,增强了面向对象的能力,等于js的扩展。但是顺带一提,ts最终编译的结果仍然是js。

2,ts增加了哪些能力?
ts的数据类型可以定义从简单到复杂的一切类型。
增加了一些新的概念:包括接口(Interfaces)、泛型(Generics)、类(Classes)、枚举类型(Enums)、类的访问修饰符(public)
ts核心库不包含node.js

2,typescript的应用场景
增强针对js的代码补全、接口提示、跳转到定义、重构等功能:在node_moudles中的@types中的index.d.ts就是ts的类型声明文件,它为ts的类型检查提供了有力支持,使用npm install @types/sequelize --save-dev安装,在vue项目中包含有,用来检测js语法规范

3,typescript如何使用
(假如项目中没有webpack,需要 安装编译工具):npm install -g typescript,将ts编译为js:tsc  hello.ts   

5,ts的语法规则
  数据类型
     原始数据类型:boolean、number、string、null、undifined、void、以及 ES6 中的新类型 Symbol 和 BigInt
     对象类型:数组、函数、对象、类、Boolean、Error、Date......包括js中定义好的所有对象以及DOM和BOM对象
     任意类型:any
      注意一:undefined和null是所有类型的子类型,可以赋值给任意类型的变量
    定义变量 
     使用 : 指定变量的类型,: 的前后有没有空格都可以,例如name: string,其中的name表示变量名,string表示变量类型是string字符串类型。ts的类型包含所有js中定义好的更多对象,例如:

let b: Boolean = new Boolean(1);
let e: Error = new Error('Error occurred');
let d: Date = new Date();
let r: RegExp = /[a-z]/;

      也包含DOM和BOM的内置对象,例如:

let body: HTMLElement = document.body;
let allDiv: NodeList = document.querySelectorAll('div');
document.addEventListener('click', function(e: MouseEvent) {
  // Do something
});

ts中的数据类型中包含任意类型any,一般被定义为任意类型的变量,可以访问任何属性和方法(即使不存在),且返回值都是任意类型

 类型推论
 定义变量的时候如果没有指定类型且没有赋值,就会默认为any类型,后续赋值为任何类型都不会报错,但假设定义变量的时候赋值了,就会默认该变量为初始值类型,后续更改为其他类型值会报错:
let   person;   //默认为any类型
person = “bob”;
person =  13;
let   son = "amy"  ; //默认类型为string
son  =  12 ;   //error  报错
    报错位置
     假如ts的变量类型定义出错,在编译阶段会报错并能生成js文件,一旦编译为js后就不会报错了
    文件后缀
      使用ts编写的文件后缀为ts,使用ts编写的react后缀为tsx
引用第三方库
    库的使用场景主要有以下几种:

  • 全局变量:通过 <script> 标签引入第三方库,注入全局变量
  • npm 包:通过 import foo from 'foo' 导入,符合 ES6 模块规范
  • UMD 库:既可以通过 <script> 标签引入,又可以通过 import 导入
  • 直接扩展全局变量:通过 <script> 标签引入后,改变一个全局变量的结构
  • 在 npm 包或 UMD 库中扩展全局变量:引用 npm 包或 UMD 库后,改变一个全局变量的结构
  • 模块插件:通过 <script> 或 import 导入后,改变另一个模块的结构

   使用第三方库,必须引入声明文件(例如jquery.d.ts)才有代码补全、接口提示功能,整个项目只要有一处引入即可;
     情况一:作者自己写了声明文件,npm包和声明文件绑定,不需要操作:npm install jquery
     情况二: 作者没有写声明文件,但是有人帮忙发布到@types中:npm install @types/jquery --save-dev
     情况三: 作者没有写声明文件,@types也没有,npm install  jquery 然后自己写声明文件   <reference path="jQuery.d.ts"/>,并且配置文件tsconfig.json:

/path/to/project
├── src
|  └── index.ts
├── types
|  └── foo
|     └── index.d.ts
└── tsconfig.json

//tsconfig.json内容:

{
    "compilerOptions": {
        "module": "commonjs",
        "baseUrl": "./",
        "paths": {
            "*": ["types/*"]
        }
    }
}

   
编写声明文件之全局变量  
  全局变量的声明文件主要有以下几种语法:

类型断言
类型断言的意思是,先假设这个变量属于某个类型,以暂时获得该类型下的属性调用权力,防止编译报错

解决问题一:将一个联合类型断言为其中一个类型
比如假设变量A是string类型就执行代码A,假设变量A是number类型就执行代码B就可以用到类型断言:
if(A   as  string) {
//do some
}
解决问题二:将一个父类断言为更加具体的子类
假设变量A是某个class或者interface  的子类,临时获取它们的属性值

class ApiError extends Error {
    code: number = 0;
}
function isApiError(error: Error) {
    if (typeof (error as ApiError).code === 'number') {
        return true;
    }
}

解决问题三:将任何一个类型断言为 any
使用window定义全局变量:window.foo=1;由于window上没有属性foo会导致不必要的报错,此时使用类型断言:(window as any).foo=1即可;

解决问题四:将any类型断言为一个具体的类型
断言的限制

  • 要使得 A 能够被断言为 B,只需要 A 兼容 B 或 B 兼容 A 即可
    所谓的兼容,指的是A与B具有父子关系

双重断言
为了解决这种限制,出现了双重断言:即A与B不具有父子关系也能够互相进行类型断言,断言方式  :A as  any as  B
函数的定义
函数声明
  function    sum(x:number):number{
        return   x
}
函数表达式
let   sum(x:number)=>number =  function(x:number):number{
   return x
}
可选参数
一般函数要求实参的个数和形参个数相同,针对可选的参数则使用?进行定义,且必须放在参数列表的末尾:
function    sun(x:number,    y?:number){   }
参数默认值:
function sum (x:number,   y: number=1){  }
剩余参数:
剩余参数的类型实际上 是数组,直接如下定义即可
function   sum (x:number,  ...items: any[]){  }
箭头符号

接口
接口是属性和抽象方法的集合,具体方法的实现由类完成。命名要求首字母大写。ts使用接口定义对象的类型 ,且对象实例化接口时,属性需要完全与接口一致,不能减少,除非使用可选属性:也不能增加,除非使用任意属性,任意属性只能定义一个(且其他确定属性和可选属性必须是它的子集,所以任意属性一般是联合类型); 
interface  Interface_name{
   readonly name: string,   //只读属性,只能在对象被创建的时候赋值
   getAge:()=>string,  //确定属性
   height?:number  , //表示可选属性
   [propName: string]:any, //任意属性,表示属性取string的任意类型
   [propName: string]:string | number, //任意属性,表示属性取string的string或者number类型
}
let   classA:Interface ={
   name:"bib",
   getAge: ():string=>{ return 3},
   fat: "yes" 
单接口继承:
接口A   extends  接口B
多接口继承:
接口A   extends   接口B  , 接口C
数组
方式一:let  age:number[ ];  
方式二(数组泛型) let   age: Array<number>
方式三(接口表示) interface   A{  
                               [index:string]:number;
                               }
                           let   arrs: A = [1,2,3]
接口和数组
interface   Arrs{
[index: string]:number
}
let  aaa: Arrs;
aaa["age"]= 16;

类包含三个成员,字段name,构造函数以及方法
class   A{
name:string;
constructor(newname:string){
this.name = newname;
}
getname:void{
console.log( 'go')
}
}
类的修饰符
public: 公有,访问不受限制
protected:  仅限于本类和子类访问 
private: 仅限于本类访问
readonly: 只读,只能修饰属性声明,构造函数的形参
注意一:constructor被修饰为private,该类不能被继承和实例化;constructor被修饰为protected,该类不能被实例化;
注意二:readonly必须在修饰符后面,比如  public readonly   name
抽象类
使用abstract修饰的类,用于定义抽象函数,不允许被实例化,子类必须实现其抽象方法:
abstract  class  A{
public   name;
 constractor(){}
 abstract  getname()
}
枚举enum
enum  people{ bob,  amy,   jerry,  jack}
自动赋值:成员bob等按照从0升序赋值,跨度为1
枚举值和枚举名反向映射:people["bob"] //得0,    people[0]  //得bob
手动赋值: enum  people{ bob=100,amy,jerry,jack}
计算所得项:enum  people{ bob,  amy,   jerry="java".length}
常数枚举:const  enum people{ bob, amy, jerry}  ,常数枚举不能包含计算所得项

keyof

是个类型运算符,针对对象,可以读取对象的键。

场景:实现Pick函数

type Pick<T,P extends keyof T> = {
   [K in P]:T[K]
}

映射类型[ ]:string

场景:表示类型A里面所有属性的key都是string,value都是boolean

type A = {
[key:string]: boolean
}

映射修改器+-

type A={
-readonly[key:string]-?: boolean; //去掉readonly和可选属性
}

键取别名as

type A<T> = {
[K in T as `get${K}`]:boolean
}

内置函数

Omit<T,"name" |"age">:除了name/age以外的属性都保留

Pick<T, "name | "age">:只要name/age

Exclude<T, "name">:除了name以外都其他值(T必须是联合类型)

Capitalize<“hello">:将首字母大写Hello

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值