还在犹豫学不学TS?看我完事>v<

前言

你们都知道Vue3开始全面支持Typescript,并且ts自己支持es5和es6写法,因此学起来其实并不复杂,难度大概和刚开始js学完学es6难度差很少,趁着这两天有时间,本身总结下,欢迎评论留言交流,若有不对的地方,会及时更正,还望见谅,这些都是我我的笔记总结的es6

  • ts有点多 这确定是个体力活 但愿你们能给个三连 >B<

TS铺垫

TS的优点

TypeScript 的优点和收益是什么?web

  • 类型系统可在编译阶段发现大部ipt 下降了使用成本

TS安装

  • 1.安装 TypeScript
$ npm install -g typescript
复制代码
  • 2.编译 TypeScript 文件
$ tsc helloworld.ts
复制代码

TS中文网typescript

TS在线运行代码npm


TS的基本类型

number数字类型

let count: number = 666;
 // ES5:var count = 666; 复制代码

String字符串类型

let csgo: string = "rush B";
 // ES5:var csgo = 'rush B'; 复制代码

Boolean 类型

let isOver: boolean = true;
 // ES5:var isOver = true;  复制代码

Array数组类型

let arr: number[] = [1, 2, 3];
// ES5:var arr = [1,2,3];  let arr: Array<number> = [1, 2, 3]; // Array<number>泛型语法 // ES5:var arr = [1,2,3]; 复制代码

Object对象类型

const obj:object={}
复制代码

以上在js类型中也有,那么下面介绍下ts比js多出的一些类型数组

Any 任何类型

在 TypeScript 中,任何类型均可以被归为 any 类型。 能被任何人赋值dom

let coco: any = 666;
coco = "字符串也能够哦"; coco = false; 复制代码

Enum 枚举类型

理解为存常量的特殊对象便可编辑器

enum Animal {
 CAT = 'cat',  DOG = 'dog',  MOUSE = 123, } console.log( Animal.CAT )//cat console.log(Animal['CAT'])//cat 复制代码

枚举成员会被赋值为从 0 开始递增的数字,同时也会对枚举值到枚举名进行反向映射:ide

enum Days {Sun, Mon, Tue, Wed, Thu};
console.log(Days["Sun"] === 0); // true console.log(Days["Mon"] === 1); // true console.log(Days["Thu"] === 4); // true  console.log(Days[0] === "Sun"); // true console.log(Days[1] === "Mon"); // true console.log(Days[2] === "Tue"); // true 复制代码

固然你也能够设置初始值函数

enum Days {Sun = 3, Mon = 1, Tue, Wed, Thu, Fri, Sat};
复制代码

Unknown 未知类型

就像全部类型均可以被归为 any,全部类型也均可以被归为 unknown any用来约束 ,而 unknown用来判定为不肯定值工具

let value: unknown;
 value = true; // OK value = 42; // OK //和any好像? 复制代码

未知类型只能赋值给自身以及any

let value: unknown;
 let value1: unknown = value; // OK let value2: any = value; // OK let value3: boolean = value; // Error let value4: number = value; // Error let value5: string = value; // Error let value6: object = value; // Error let value7: any[] = value; // Error let value8: Function = value; // Error 复制代码

Tuple 元祖类型

固定长度,固定类型

let tup: [number, string] = [27, "jianan"];
console.log(tup);//let tup: [number, string] 复制代码

Void 空类型

约束函数的返回值,表示该函数没有返回任何值 也就是 不return

// 声明函数返回值为void
function warnUser(): void {  console.log("不会return任何东西"); } 复制代码
固然你不写void, ts类型推导会推出来你没有return 就会显示为void
固然你不写void, ts类型推导会推出来你没有return 就会显示为void

Never 永不存在值类型

表示该函数永远不会结束 好比报错类型语句 死循环

function error(message: string): never {
 throw new Error(message); } 复制代码

接下来咱们补充一些关键字,以便咱们学习Type和接口以及泛型可以更好地理解


断言

也就是强制性的修改其数据类型

类型断言as

  • as断言

  • <断言>值

let someValue: any = "this is a string";
 // 'as'语法:值 as 类型 let strLength: number = (someValue as string).length;  // '尖括号'语法:<类型>值 let strLength2: number = (<string>someValue).length; 复制代码

非空断言

肯定其有值,不会null和undefiend

function sayHello2(name: string | undefined) {
 let sname: string = name!;//!感叹号哦 就这个  } 复制代码

  


类型判断

typeof 类型演算

const a: number = 3
// 至关于: const b: number = 4 const b: typeof a = 4 复制代码

instanceof 推断类型

let obj = 0.5 < Math.random() ? new String(1) : new Array(1);
if(obj instanceof String){  // obj推断为String类型  obj+= '123' } else {  // obj为any[]类型  obj.push(123); } 复制代码

类型别名 和 接口

这2个算是TS中比较重要用的也较多的,均可以用于约束 类、对象、函数的契约

先来写简单的

type one = {
 name: string,  age: number } let obj: one = {  name: '嘤嘤嘤',  age: 18 } 复制代码

再看看接口

interface two {
 love: string,  disg: () => boolean } let obj: two = {  love: '勒布朗詹姆斯',  disg: () => true } 复制代码
  • Type和interface很是的类似 再看看他们应用在各类类型上如何约束↓

约束类

interface ClockInterface {      // 同理type也能够 type ClockInterface={}
 currentTime: Date;  setTime(d: Date): string; }  class Clock implements ClockInterface {  public currentTime: Date;  setTime(d: Date) {  this.currentTime = d;  return '嘿嘿嘿'  }  constructor(h: number, m: number) { } } 复制代码

约束对象

type和interface均可以
interface Husband { //type Husband ={}  sex:string  interest:string  age:number } let myhusband:Husband ={ sex:'男',interest:'看书、做家务',age:18} 复制代码

约束函数

//type和interface均可以
interface SearchFunc { //type SearchFunc={}  (source: string, subString: string): boolean; }  let mySearch: SearchFunc = (source, subString) => {  return true; } 复制代码

约束数组

//type和interface均可以
interface NumberArray { //type NumberArray = {}  [index: number]: number; }  let fibonacci: NumberArray = [1, 1, 2, 3, 5]; 复制代码

约束对象 属性值和属性名

//type和interface均可以 
interface Dictionary<T> { //type Dictionary = {}  [index: string]: T; //属性名:string : 属性值外界定 };  const data:Dictionary<number> = {  a: 3,  b: 4 } 复制代码

类型别名和接口的区别

继承方法不一样

Type是使用交叉类型&进行继承,而interface使用的是extends 他们还能互相继承?

  • 接口 继承 接口(extends)
interface Name { 
 name: string; } interface User extends Name {  age: number; }  const obj:User={  name:'123',  age:321 } 复制代码
  • 别名 继承 别名 (&)
type Name = { 
 name: string; } type User = Name & { age: number };  const obj:User={  name:'123',  age:321 } 复制代码
  • 接口 继承 别名
type Name = {  name: string; } interface User extends Name {  age: number; } const obj:User={  name:'123',  age:321 } 复制代码
  • 别名 继承 接口
interface Name { 
 name: string; } type User = {  age: number; }& Name const obj:User={  name:'123',  age:321 } 复制代码

接口能够而别名不行的

interface有个特性,就是屡次声明会进行合并

interface User {
 name: string  age: number } interface User {  sex: string } /* User 接口为 {  name: string  age: number  sex: string } */ 复制代码

别名能够而接口不行的

type能够声明 基本类型,联合类型,元组 的别名,interface不行

// 基本类型别名
type Name = string  // 联合类型 interface Dog {  wong(); } interface Cat {  miao(); }  type Pet = Dog | Cat  // 具体定义数组每一个位置的类型 type PetList = [Dog, Pet]  //interface why = Pet|PetList //error 复制代码

type 支持类型映射,interface不支持 支持映射的type成为了泛型的宠儿

type Keys = "firstname" | "surname"
 type DudeType = {  [key in Keys]: string }  const test: DudeType = {  firstname: "Pawel",  surname: "Grzybek" }  // 报错 //interface DudeType { // [key in keys]: string //} 复制代码

TS中的类

在 TypeScript 中,咱们能够经过 Class 关键字来定义一个类:

class rushB {
 // 静态属性  static cname: string = "rushB";  // 成员属性  heihei: string;   // 构造函数 - 执行初始化操做  constructor(message: string) {  this.heihei = message;  }   // 静态方法  static getClassName() {  return "A1高闪来一个";  }   // 成员方法  greet() {  return "我就喜欢, " + this.heihei;  } }  let obj = new rushB("哈哈哈");  复制代码

访问权限修饰符

  • public: 默认的, 公开的,全部代码都能在内外访问到
  • private 私有的, 只有在类中才能够访问
  • protected 受保护的修饰符(只能在自身和派生类(子类)中访问到)
  • static : 它们不须要实例化,而是直接经过类来调用:
class Hello {
 constructor(name: string, age: number) {  this.name = name;  this.age = age;  }  public name: string; // 这个是对后文this.name类型的定义  public age: number;  private password: '这是私有的,只有我本身能访问'  protected file:'这个只有我活着继承个人子类能够访问'  print() {  return this.name + this.age;  } }  let hello = new Hello('name', 18); 复制代码

存取器

设置器set / 读取器get 控制属性的读取和赋值

class Hello {
 private _age: number;  get age(): number {  return this._age;  }  set age(age: number) {  if (age > 0 && age < 100) {  console.log("年龄在0-100之间"); // 年龄在0-100之间  return;  }  this._age = age;  } }  let hello = new Hello(); hello.age = 23; console.log(hello.age) 复制代码

类继承+约束

interface A {
 age: number } class B {  constructor(name: string) {  this.name = name;  }  name: string } class C extends B implements A {  constructor() {  super('BBBBBB')  }  age = 123;  tell() { console.log(this.age, this.name) } }  let hh = new C() hh.tell();//123 BBBBBB 复制代码

补充关键字

接下来准备泛型了 算是TS中的重量级选手 咱们须要补充一些知识点

keyof 获取类型约束

interface Point {
 x: number;  y: number; }  type keys = keyof Point;// type keys = "x" | "y" 复制代码

in 配合keyof能够进行遍历

interface Duck {
 age: 10  name: 'duck' }  type obj = {  [p in keyof Duck]: Duck[p] // age: 10 name: 'duck' } 复制代码

下面2个用到了泛型 你们能够先去泛型看完再回头看,由于我不想又分开来省得你们来回跑

extends 继承

extends 能够用来继承一个类,也能够用来继承一个 interface,但还能够用来判断有条件类型

T extends U ? X : Y;
复制代码
  • 用来表示类型是不肯定的, 若是U的类型能够表示T, 那么返回X, 不然Y.
  • 挺绕的那看看这个把
type Words = 'a'|'b'|"c";
 type W<T> = T extends Words ? true : false;  type WA = W<'a'>; // -> true type WD = W<'d'>; // -> false  复制代码

a 能够赋值给 Words 类型,因此 WA 为 true,而 d 不能赋值给 Words 类型,因此 WD 为 false。

infer 类型推导

就是字面意思 推断,柯南,懂? -.-

  • 看看源码实现
type ReturnType<T> = T extends (
 ...args: any[] ) => infer R  ? R  : any; 复制代码

其实这里的 infer R 就是声明一个变量来承载传入函数签名的返回值类型, 简单说就是用它取到函数返回值的类型方便以后使用。

我本身把本身写懵了,上面话我本身都听不太懂,话说infer真的难理解,看看下面的例子

T extends (...args: infer P) => any ? P : never;

  • 上面声明一个P用来表示...args可能的类型,
  • 若是(...args: infer P)能够表示 T, 那么返回...args对应的类型, 也就是函数的参数类型, 反之返回never.
  • 更好理解的是 infer P 他接收了P 而且不管如何都返回 由于他的断定条件为any 确定返回 说实话我不知道是否是这样理解的,我只能大概的理解成这样,但愿大佬看到能完善下小弟的意思

泛型

泛型就是解决 类 接口 方法的复用性、以及对不特定数据类型的支持

  • 来看看怎么用的吧 冲冲冲

2种定义泛型方式

function gen_func1<T>(arg: T): T {
 return arg; } 复制代码
let gen_func2: <T>(arg: T) => T = function (arg) {  return arg; } 复制代码

使用泛型

function identity <T>(value: T) : T {
 return value;  }   console.log(identity<Number>(1)) // 1 Number传入到了 identity中的全部T中 复制代码


多泛型

这里的返回值还用到了联合类型哦

function CSGO <T, U>(value: T, message: U) : T|U {
 console.log(message);  return value; }  console.log(CSGO<Number, string>(66, "RushB")); 复制代码


泛型接口/别名

  • 类型别名和接口差很少的
interface CSGO<V, M> {
 target: V,  message: M }  let obj: CSGO<string, number> = {  target: 'B',  message: 666 } 复制代码


泛型类

interface GenericInterface<U> {
 value: U  getIdentity: () => U  }   class IdentityClass<T> implements GenericInterface<T> {  value: T   constructor(value: T) {  this.value = value  }   getIdentity(): T {  return this.value  }   }   const myNumberClass = new IdentityClass<Number>(24);  console.log(myNumberClass.getIdentity()); // 24   const myStringClass = new IdentityClass<string>("累了,复制粘贴例子算了!");  console.log(myStringClass.getIdentity()); // 累了,复制粘贴例子算了!  复制代码

泛型参数默认类型

interface A<T=string> {
 name: T; }  const strA: A = { name: "老八蜜汁小伙伴" }; const numB: A<number> = { name: 404 }; 复制代码


泛型工具类型

这里就开始舒服起来了,封装了许多好用的

Partial 将类型T的成员变为可选

interface User {
 id: number; }; // 至关于: type PickUser = { id?: number} type PickUser = Partial<User>  //实现原理// type Partial<T> = {//全部为可选-? [P in keyof T]?: T[P]; }; 复制代码

Required 将类型T中的成员变为必填

type User = {
 id: number; }; // 至关于: type PickUser = { id: number} type PickUser = Partial<User>  //实现原理// type Partial1<T> = { //全部为必选 [P in keyof T]-?: T[P]; }; 复制代码

Readonly 将类型T中的成员变为只读

//使用方式
type PickUser = Readonly<User> //实现原理// type Partial1<T> = { //全部为必选  readonly[P in keyof T]: T[P]; }; 复制代码

Exclude<T,U> 抽离出T能够给U赋值的值

``` js
复制代码

//使用方法 type A = Exclude<'x' | 'a', 'x' | 'y' | 'z'> //type A = 'a'

//实现原理// type Exclude<T, U> = T extends U ? never : T;

 ## Extract<T,U> 抽离出T和U的共同值 ``` js type A = Extract<'x' | 'a' | 'c', 'x' | 'y' | 'a'> //type A = 'x'|'a'  //实现原理// type Extract<T, U> = T extends U ? T : never; 复制代码

ReadonlyArray 使数组变为不可赋值

let arr: ReadonlyArray<string> = ["a", "b"];
//arr:readonly string[] arr.push("c"); // error arr[0] = "c"; // error 复制代码

NonNullable 去除T中的null和undefined

``` js
复制代码

type User = 'a' | 'b' | null | undefined

type aaa = NonNullable // aaa = 'a'|'b'

 ## Parameters<T>获取函数参数的类型,返回数组形式 ```js function cba(a: number, b: string) {return a + b} type nba = Parameterss<typeof cba> //nba = [number,string]  //实现原理// type Parameterss<T extends (...args: any) => any> = T extends (...args: infer P) => any ? P : never; 复制代码

ConstructorParameters获取class构造函数的参数类型,返回数组形式

class abc{}
type aaa= new(a:number ,b:any)=> abc type nba = ConstructorParameters<aaa> //nba = [number,any] 复制代码

ReturnType 获取函数 返回值 类型

function abc(a: number, b: number) {
 return `${a + b}`//string } type cba = ReturnType<typeof abc>//typeof判断返回值为string //cba=string  //实现原理// type ConstructorParameters<T extends new (...args: any) => any> = T extends new (...args: infer P) => any ? P : never; 复制代码

InstanceType获取构造函数类型的实例成员

//例子1class Animal {}
type Result = InstanceType<typeof Animal>;//类型为Animal //例子2 class abc{} type z = new()=>abc type Result2 = InstanceType<z>;//类型为abc 复制代码

ThisType 设置对象的this

interface Person {
 name: string  age: number } //[k: string]: any 对象的每一位属性名为字符串 属性值为anyZ type ObjType = { [k: string]: any } & ThisType<Person> const obj: ObjType = {  a:1,  method(arg1: boolean) {  // this的类型被约束为Person  console.log(this.age)  } } 复制代码

Omit<T,K> 将K属性从T校验对象中剔除掉

interface User {
 id: number;  age: number;  name: string; };  // 将id从校验对象中剔除 至关于: type PickUser = { age: number; name: string; }  type OmitUser = Omit<User, "id"> //实现原理// type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>; 复制代码

Pick<T,K>, 只保留本身选择的属性, K表明要保留的属性键值

这个有什么意义不懂

type A  = Pick<{a:number,b:string,c:boolean}, 'a'|'b'>
type A1 = Pick<A, 'a'|'b'> // {a:number,b:string} 复制代码

中午1点到如今,接近4小时终于完成了,TS真的是多,但愿能够帮到你们,这些是我学习ts记录的笔记分享给你们 (^▽^) 给个三连哦

相关文章
相关标签/搜索