摘要:直達第一課體驗第二課基礎類型和入門高級類型第三課泛型第四課解讀高級類型第五課什么是命名空間回顧第二課的時候為了更好的講解基礎類型所以我們講解了一部分高級類型比如接口聯合類型交叉類型本節課我會把剩余高級類型都講完知識點摘要本節課主要關鍵詞為自
直達
第一課, 體驗typescript
第二課, 基礎類型和入門高級類型
第三課, 泛型
第四課, 解讀高級類型
第五課, 什么是命名空間(namespace)?
回顧第二課的時候為了更好的講解基礎類型, 所以我們講解了一部分高級類型, 比如"接口( interface )" / "聯合類型( | )" / "交叉類型( & )", 本節課我會把剩余高級類型都講完.
知識點摘要本節課主要關鍵詞為: 自動類型推斷 / 類型斷言 / 類型別名(type) / 映射類型(Pick/Record等...) / 條件類型(extends) / 類型推斷(infer)
自動類型推斷(不用你標類型了,ts自己猜)第二課我們講了那么多基礎類型, 大家現在寫ts的時候一定會在每個變量后面都加上類型吧? 但是?
現在告訴大家有些情況下你不需要標注類型, ts可以根據你寫的代碼來自動推斷出類型:
let n = 1; // ts會自動推斷出n是number類型 n+=3 // 不報錯,因為已知類型 let arr1 = []; // 類型為: any[] arr1.push(1,"2", {o:3}); let arr = [1]; // 內部要有數字, 才能推斷出正確類型 arr.push(2);
let n: number|null = 0.5 < Math.random() ? 1:null; if(null !== n){ n+=3 // ts知道現在n不是null是number }
document.ontouchstart = ev=>{ // 能自動推斷出ev為TouchEvent console.log(ev.touches); // 不報錯, TouchEvent上有touches屬性 }
typeof就是js中的typeof, ts會根據你代碼中出現的typeof來自動推斷類型:
let n:number|string = 0.5 < Math.random()? 1:"1"; // 如果沒有typeof, n*=2會報錯, 提示沒法推斷出當前是number類型, 不能進行乘法運算 if("number" === typeof n) { n*= 2; } else { n= "2"; }
注意: 在ts文檔中, 該部分的知識點叫做typeof類型保護, 和其他類型推斷的內容是分開的, 被寫在高級類型/類型保護章節中.
ts會根據你代碼中出現的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); }
注意: 在ts文檔中, 該部分的知識點叫做instanceof類型保護, 和其他類型推斷的內容是分開的, 被寫在高級類型/類型保護章節中.
類型斷言(你告訴ts是什么類型, 他都信)有些情況下系統沒辦法自動推斷出正確的類型, 就需要我們標記下, 斷言有2種語法, 一種是通過"<>", 一種通過"as", 舉例說明:
let obj = 0.5 < Math.random() ? 1 : [1]; // number|number[] // 斷言, 告訴ts, obj為數組 (類型別名(type)obj).push(1); //等價 (obj as number[]).push(1);
類型別名可以表示很多接口表示不了的類型, 比如字面量類型(常用來校驗取值范圍):
type A = "top"|"right"|"bottom"|"left"; // 表示值可能是其中的任意一個 type B = 1|2|3; type C = "紅"|"綠"|"黃"; type D = 150; let a:A = "none"; // 錯誤, A類型中沒有"none"
interface A1{ a:number; } type B = A1 | {b:string}; type C = A1 & {b:string}; // 與泛型組合 type D索引類型(keyof)= A1 | T[];
js中的Object.keys大家肯定都用過, 獲取對象的鍵值, ts中的keyof和他類似, 可以用來獲取對象類型的鍵值:
type A = keyof {a:1,b:"123"} // "a"|"b" type B = keyof [1,2] // "1"|"2"|"push"... , 獲取到內容的同時, 還得到了Array原型上的方法和屬性(實戰中暫時沒遇到這種需求, 了解即可)
可以獲得鍵值, 也可以獲取對象類型的值的類型:
type C = A["a"] // 等于type C = 1; let c:C = 2 // 錯誤, 值只能是1映射類型(Readonly, Pick, Record等...)
映射類型比較像修改類型的工具函數, 比如Readonly可以把每個屬性都變成只讀:
type A = {a:number, b:string} type A1 = Readonly // {readonly a: number;readonly b: string;}
打開node_modules/typescript/lib文件夾可以找到lib.es5.d.ts, 在這我們能找到Readonly的定義:
type Readonly= { readonly [P in keyof T]: T[P]; };
其實不是很復雜, 看了本節課前面前面的內容, 這個很好理解是吧:
定義一個支持泛型的類型別名, 傳入類型參數T.
通過keyof獲取T上的鍵值集合.
用in表示循環keyof獲取的鍵值.
添加readonly標記.
type A = {a:number, b:string} type A1 = Partial // { a?: number; b?: string;}
type A = {a?:number, b?:string} type A1 = Required // { a: number; b: string;}
type A = {a:number, b:string} type A1 = Pick // {a:number}
type A = {a:number, b:string} type A1 = Omit // {b:string}
type A1 = Record// 等價{[k:string]:string}
type A = {a:number, b:string} type A1 = Exclude// number // 兼容 type A2 = Exclude // never , 因為any兼容number, 所以number被過濾掉
type A = {a:number, b:string} type A1 = Extract// string
type A1 = NonNullable// number|string
type A1= ReturnType<()=>number> // number
ts中類有2種類型, 靜態部分的類型和實例的類型, 所以T如果是構造函數類型, 那么InstanceType可以返回他的實例類型:
interface A{ a:HTMLElement; } interface AConstructor{ new():A; } function create (AClass:AConstructor):InstanceType{ return new AClass(); }
返回類型為元祖, 元素順序同參數順序.
interface A{ (a:number, b:string):string[]; } type A1 = Parameters // [number, string]
和Parameters類似, 只是T這里是構造函數類型.
interface AConstructor{ new(a:number):string[]; } type A1 = ConstructorParametersextends(條件類型)// [number]
T extends U ? X : Y
用來表示類型是不確定的, 如果U的類型可以表示T, 那么返回X, 否則Y. 舉幾個例子:
type A = string extends "123" ? string :"123" // "123" type B = "123" extends string ? string :123 // string
明顯string的范圍更大, "123"可以被string表示, 反之不可.
infer(類型推斷)單詞本身的意思是"推斷", 實際表示在extends條件語句中聲明待推斷的類型變量. 我們上面介紹的映射類型中就有很多都是ts在lib.d.ts中實現的, 比如Parameters:
type Parameters為vue3學點typescript, 解讀高級類型 直達any> = T extends (...args: infer P) => any ? P : never;
第一課, 體驗typescript
第二課, 基礎類型和入門高級類型
第三課, 泛型
第四課, 解讀高級類型
回顧第二課的時候為了更好的講解基礎類型, 所以我們講解了一部分高級類型, 比如"接口( interface )" / "聯合類型( | )" / "交叉類型( & )", 本節課我會把剩余高級類型都講完.
知識點摘要本節課主要關鍵詞為: 自動類型推斷 / 類型斷言 / 類型別名(type) / 映射類型(Pick/Record等...) / 條件類型(extends) / 類型推斷(infer)
自動類型推斷(不用你標類型了,ts自己猜)第二課我們講了那么多基礎類型, 大家現在寫ts的時候一定會在每個變量后面都加上類型吧? 但是?
現在告訴大家有些情況下你不需要標注類型, ts可以根據你寫的代碼來自動推斷出類型:
let n = 1; // ts會自動推斷出n是number類型 n+=3 // 不報錯,因為已知類型 let arr1 = []; // 類型為: never[] arr1.push(1); // 報錯, let arr = [1]; // 內部要有數字, 才能推斷出正確類型 arr.push(2);
let n: number|null = 0.5 < Math.random() ? 1:null; if(null !== n){ n+=3 // ts知道現在n不是null是number }
document.ontouchstart = ev=>{ // 能自動推斷出ev為TouchEvent console.log(ev.touches); // 不報錯, TouchEvent上有touches屬性 }
typeof就是js中的typeof, ts會根據你代碼中出現的typeof來自動推斷類型:
let n:number|string = 0.5 < Math.random()? 1:"1"; // 如果沒有typeof, n*=2會報錯, 提示沒法推斷出當前是number類型, 不能進行乘法運算 if("number" === typeof n) { n*= 2; } else { n= "2"; }
注意: 在ts文檔中, 該部分的知識點叫做typeof類型保護, 和其他類型推斷的內容是分開的, 被寫在高級類型/類型保護章節中.
ts會根據你代碼中出現的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); }
注意: 在ts文檔中, 該部分的知識點叫做instanceof類型保護, 和其他類型推斷的內容是分開的, 被寫在高級類型/類型保護章節中.
類型斷言(你告訴ts是什么類型, 他都信)有些情況下系統沒辦法自動推斷出正確的類型, 就需要我們標記下, 斷言有2種語法, 一種是通過"<>", 一種通過"as", 舉例說明:
let obj = 0.5 < Math.random() ? 1 : [1]; // number|number[] // 斷言, 告訴ts, obj為數組 (類型別名(type)obj).push(1); //等價 (obj as number[]).push(1);
類型別名可以表示很多接口表示不了的類型, 比如字面量類型(常用來校驗取值范圍):
type A = "top"|"right"|"bottom"|"left"; // 表示值可能是其中的任意一個 type B = 1|2|3; type C = "紅"|"綠"|"黃"; type D = 150; let a:A = "none"; // 錯誤, A類型中沒有"none"
interface A1{ a:number; } type B = A1 | {b:string}; type C = A1 & {b:string}; // 與泛型組合 type D索引類型(keyof)= A1 | T[];
js中的Object.keys大家肯定都用過, 獲取對象的鍵值, ts中的keyof和他類似, 可以用來獲取對象類型的鍵值:
type A = keyof {a:1,b:"123"} // "a"|"b" type B = keyof [1,2] // "1"|"2"|"push"... , 獲取到內容的同時, 還得到了Array原型上的方法和屬性(實戰中暫時沒遇到這種需求, 了解即可)
可以獲得鍵值, 也可以獲取對象類型的值的類型:
type C = A["a"] // 等于type C = 1; let c:C = 2 // 錯誤, 值只能是1映射類型(Readonly, Pick, Record等...)
映射類型比較像修改類型的工具函數, 比如Readonly可以把每個屬性都變成只讀:
type A = {a:number, b:string} type A1 = Readonly // {readonly a: number;readonly b: string;}
打開node_modules/typescript/lib文件夾可以找到lib.es5.d.ts, 在這我們能找到Readonly的定義:
type Readonly= { readonly [P in keyof T]: T[P]; };
其實不是很復雜, 看了本節課前面前面的內容, 這個很好理解是吧:
定義一個支持泛型的類型別名, 傳入類型參數T.
通過keyof獲取T上的鍵值集合.
用in表示循環keyof獲取的鍵值.
添加readonly標記.
type A = {a:number, b:string} type A1 = Partial // { a?: number; b?: string;}
type A = {a?:number, b?:string} type A1 = Required // { a: number; b: string;}
type A = {a:number, b:string} type A1 = Pick // {a:number}
type A = {a:number, b:string} type A1 = Omit // {b:string}
type A1 = Record// 等價{[k:string]:string}
type A = {a:number, b:string} type A1 = Exclude// number // 兼容 type A2 = Exclude // never , 因為any兼容number, 所以number被過濾掉
type A = {a:number, b:string} type A1 = Extract// string
type A1 = NonNullable// number|string
type A1= ReturnType<()=>number> // number
ts中類有2種類型, 靜態部分的類型和實例的類型, 所以T如果是構造函數類型, 那么InstanceType可以返回他的實例類型:
interface A{ a:HTMLElement; } interface AConstructor{ new():A; } function create (AClass:AConstructor):InstanceType{ return new AClass(); }
返回類型為元祖, 元素順序同參數順序.
interface A{ (a:number, b:string):string[]; } type A1 = Parameters // [number, string]
和Parameters類似, 只是T這里是構造函數類型.
interface AConstructor{ new(a:number):string[]; } type A1 = ConstructorParametersextends(條件類型)// [number]
T extends U ? X : Y
用來表示類型是不確定的, 如果U的類型可以表示T, 那么返回X, 否則Y. 舉幾個例子:
type A = string extends "123" ? string :"123" // "123" type B = "123" extends string ? string :123 // string
明顯string的范圍更大, "123"可以被string表示, 反之不可.
infer(類型推斷)單詞本身的意思是"推斷", 實際表示在extends條件語句中聲明待推斷的類型變量. 我們上面介紹的映射類型中就有很多都是ts在lib.d.ts中實現的, 比如Parameters:
type Parametersany> = T extends (...args: infer P) => any ? P : never;
上面聲明一個P用來表示...args可能的類型, 如果(...args: infer P)可以表示 T, 那么返回...args對應的類型, 也就是函數的參數類型, 反之返回never.
注意: 開始的T extends (...args: any) => any用來校驗輸入的T是否是函數, 如果不是ts會報錯, 如果直接替換成T不會有報錯, 會一直返回never.
接下來我們利用infer來實現"刪除元祖類型中第一個元素", 這常用于簡化函數參數, 這有一個我之前的應用
export type Tail總結= ((...args: Tuple) => void) extends ((a: any, ...args: infer T) => void) ? T : never;
多寫多練, 很快就上手, 放幾個我用ts寫的項目當做參考, 拋磚引玉, 加油!
手勢庫: https://github.com/any86/any-...
命令式調用vue組件: https://github.com/any86/vue-...
工作中常用的一些代碼片段: https://github.com/any86/usef...
一個mini的事件管理器: https://github.com/any86/any-...
上面聲明一個P用來表示...args可能的類型, 如果(...args: infer P)可以表示 T, 那么返回...args對應的類型, 也就是函數的參數類型, 反之返回never.
注意: 開始的T extends (...args: any) => any用來校驗輸入的T是否是函數, 如果不是ts會報錯, 如果直接替換成T不會有報錯, 會一直返回never.
接下來我們利用infer來實現"刪除元祖類型中第一個元素", 這常用于簡化函數參數, 這有一個我之前的應用
export type Tail總結= ((...args: Tuple) => void) extends ((a: any, ...args: infer T) => void) ? T : never;
多寫多練, 很快就上手, 放幾個我用ts寫的項目當做參考, 拋磚引玉, 加油!
手勢庫: https://github.com/any86/any-...
命令式調用vue組件: https://github.com/any86/vue-...
工作中常用的一些代碼片段: https://github.com/any86/usef...
一個mini的事件管理器: https://github.com/any86/any-...
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/106216.html
摘要:更新啦第一課體驗第二課基礎類型和入門高級類型第三課泛型第四課解讀高級類型要來了看了的視頻特別興奮要來了是用開發的我揣測在的帶領下會成為主流呢要不先學點年最酷的前端技術我是年初開始使用的自從開始用上了就喜歡上了真的愛不釋手最愛他幾點很多小錯誤 更新啦 第一課, 體驗typescript 第二課, 基礎類型和入門高級類型 第三課, 泛型 第四課, 解讀高級類型 vue3要來了 看了vue ...
摘要:導航第一課體驗第二課基礎類型和入門高級類型第三課泛型第四課解讀高級類型很重要這一節很重要可以說是的最核心部分這一節學完其實就可以開始用寫代碼了想想中的再看看標題中的類型字所以請大家務必認真什么是入門高級類型因為高級類型的內容比較多但是有些基 導航 第一課, 體驗typescript 第二課, 基礎類型和入門高級類型 第三課, 泛型 第四課, 解讀高級類型 很重要 這一節很重要, 可以說...
摘要:往期第一課體驗第二課基礎類型和入門高級類型第三課泛型第四課解讀高級類型插一課本來打算接著上節課把高級類型都講完但是寫著寫著我發現高級類型中有很多地方都需要泛型的知識那么先插一節泛型什么是類型變量和泛型變量的概念我們都知道可以表示任意數據類型 往期 第一課, 體驗typescript 第二課, 基礎類型和入門高級類型 第三課, 泛型 第四課, 解讀高級類型 插一課 本來打算接著上節課, ...
摘要:往期目錄第一課體驗第二課基礎類型和入門高級類型第三課什么是泛型第四課解讀高級類型第五課什么是命名空間什么時候要用命名空間如果你發現自己寫的功能函數類接口等越來越多你想對他們進行分組管理就可以用命名空間下面先用類舉例仔細看你會發現下還有在這里 往期目錄 第一課, 體驗typescript 第二課, 基礎類型和入門高級類型 第三課, 什么是泛型? 第四課, 解讀高級類型 第五課, 什么是命...
閱讀 645·2021-08-17 10:15
閱讀 1742·2021-07-30 14:57
閱讀 1980·2019-08-30 15:55
閱讀 2823·2019-08-30 15:55
閱讀 2712·2019-08-30 15:44
閱讀 676·2019-08-30 14:13
閱讀 2389·2019-08-30 13:55
閱讀 2595·2019-08-26 13:56