還在猶豫學不學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記錄的筆記分享給你們 (^▽^) 給個三連哦

相關文章
相關標籤/搜索