摘要:為了由簡入繁,不妨將這些類型劃分為基本類型復合類型。以下將漸進式的對的這些類型進行了解。實際上,有一種屬性描述對象,是通過獲取的。但無論如何,類型檢查是可以排除大部分錯誤的。在函數的類型聲明中,繼續來鞏固這條規則的寫法。
幾個月前把 ES6 的特性都過了一遍,收獲頗豐。現在繼續來看看 TypesScript(下文簡稱為 “TS”)。限于經驗,本文一些總結如有不當,歡迎指正。
概述官網有這樣一段描述:
TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.
說的是 TS 是 JS 的超集,并且可以編譯成普通的 JS。
其中, 超集 的定義是:
如果一個集合 S2 中的每一個元素都在集合 S1 中,且集合 S1 中可能包含 S2 中沒有的元素,則集合 S1 就是 S2 的一個超集,反過來,S2 是 S1 的子集。
而實際上,“超出” 的部分主要就是 “類型系統”。因此可以這樣歸納:
TS ≈ ES6 + 類型系統
ES6 是 ES5 轉向主流語規格的一個重要升級,順著這個角度看,TS 讓這門語言披上一層類型的外衣,直接演變成一種強類型的語言;從相反角度看,TS 將編程語言們一些主流的特性引入到了 JS 的世界。
平穩過渡TypeScript 設計巧妙,兼具微軟工業化的水準。首先,它僅靠一行命令,就融入到了廣大前端人的世界:
npm install -g typescript
然后由你隨便挑一個曾編寫的 .js 腳本文件(不妨叫做hello.js),不用對內容做任何修改,直接將文件后綴改成 .ts。這樣,你就已經完成了一份 TypeScript 腳本的編寫!
然后編譯它:
tsc hello.ts
OK,你已經平滑過渡到了 TS 的世界。就是這么簡單!
當然這只是“一小步”,似乎后邊還有無數的坑要填。不用擔心,TS 已經填平了大部分的坑!
比如,時下最流行的 gulp,webpake 工具,只需做一些簡單的配置,就能接引入TypeScript 進行編譯;同時為了能與 React 完美融合,TS 引入了與 JSX 類似的 TSX 語法。當然,TS 在 Angular、Vue.js 以及 Node.js 中也是暢通的......
坑都填平了,大家過渡起來自然順心順手。
基本類型與 ES6 一脈相承的,同時也接軌大部分強類型語言,TS 的類型大概有這些:
1),Number、Boolean、String、Null 、undefined、Symbol
2), Array、Function、Object
3),Tuple、enum、Void、 Never、Any
TS 作為 JS 的一個超集,在 JS 的基礎上擴展了一些非常有用的類型。第 3)中的類型就是從一些強類型語言引入的類型。
為了由簡入繁,不妨將這些類型劃分為:基本類型、復合類型。復合類型 一般由 基本類型 構成。以下將漸進式的對 TS 的這些類型進行了解。
如何做類型聲明?強類型語言都有一套類型聲明的語法規則,TS 也不例外。TS 采用類型注釋的寫法,像這樣將一個帶冒號的注釋,置于聲明變量名之后,就構成了 TS 類型聲明的語法。
let str : string = "hello typescript";
JAVA 的寫法是相反的,但無實質差別:
String str = "hello java";
這樣的注釋如同一種補充說明,后文將簡稱它為 “冒號注釋”,熟悉書寫規則,有利于快速進入到 TS 的代碼世界。
實際上,ES6 有一種屬性描述對象,是通過Object.getOwnPropertyDescriptor(obj, key) 獲取的。
let obj = { set name(val) {} } Object.getOwnPropertyDescriptor(obj, "name"); // { // configurable: true // enumerable: true // get: undefined // set: ? a(val) // }
如果將 setter 類型的 name 方法適當改寫,我們甚至可以實現 obj.name 賦值的類型檢查功能,也非常有意思。
同樣的,冒號注釋 : string 也可以理解為對一個 str 變量的描述。憑借這個注釋的描述,TS 的類型編譯器就能進行類型檢查了。
建立了類型的認知后,繼續跑馬圈地,鞏固認知。其中,Function、 Never、Any 規則稍顯復雜,但也沒有什么特別的,留后細說。
簡單的基本類型// boolean 類型 let isBool: boolean = 1 < 5; // string 類型 let str: string = "hello world"; // number 類型 let num: number = 123; // void 類型 let unusable: void = undefined; // undefined 類型 let u: undefined = undefined; // null 類型 let n: null = null; //Symbol 類型 // 類型 symbol 小寫也能編譯通過 let sym: Symbol = Symbol("hello");簡單的復合類型。
// object 類型 let obj : object = {}; let arrObj : object = []; let funcObj : object = () => {}; // array 類型 let arrNum : number[] = [1, 2, 3] let arrStr : string[] = ["a", "b", "c"] let arrObj : object[] = [{}]; // 元組 類型 let tup : [number, string] = [1, "hello"]; // 枚舉類型 enum Days {Sun, Mon, Tue, Wed, Thu, Fri, Sat};
可謂一覽無余,類型的語法就是冒號注釋,僅憑這一條,60~70% 的情況你都無需擔心自己的類型書寫有誤。
一個靈活的子類型但 JS 的動態類型太靈活了,null 和 undefined 的相似性, Array、Function 和 Object的糾纏不清的關系,僅憑一招恐怕還很難駕馭的住 JS 的 “多動癥” 般的類型。比如:
// boolean 類型接收這樣的賦值 let isBool_n: boolean = null; let isBool_u: boolean = undefined; // void 類型接收這樣的賦值 let unusable: void = undefined; unusable = null; // Symbol 類型接收這樣的賦值 let sym: Symbol = Symbol("hello"); sym = null; sym = undefined; // object 類型接收這樣的賦值 let obj : object = {}; obj = null; obj = undefined;
它們都能編譯通過。但是 null 不屬于 boolean 類型,undefined也并不屬于object 類型,為什么能通過類型檢查?
事實上,undefined 和 null 是所有類型的子類型。也就是說,它們倆可以作為值賦給任何類型的變量。甚至,它們倆可以互相賦值給對方。
// undefined 類型 let u: undefined = null; // null 類型 let n: null = undefined;
有了這一條規則,就能解釋一些 “復合類型” 中遇到的問題:
let arrNum: number[] = []; let arrStr: string[] = []; // undefined 也屬于 number 類型 let arrNum: number[] = [undefined]; // undefined 也屬于 object 類型 let obj : object = undefined;
有了這條規則,我們可以大膽的寫 TS 的類型聲明了。
但太過放開的規則——本文姑且稱之為 “混雜模式”,又似乎一下子讓 TS 退回到了 JS 的動態類型的原始狀態了,讓習慣了強類型的同學容易懵掉,也讓從 JS 轉 TS 的同學體會不到強類型的好處。
畫條界限好在,TS 設計了一套巧妙的類型系統,猶如給 JS 披上 了一層強大的盔甲。
TS 在 “混雜模式” 下,可能存在這樣的風險,就是:編譯正確,運行出錯。比如:
// 無意獲得一個 undefined 作為初始值 let init_name = undefined; let nameList: string[] = [init_name]; console.log(nameList[0].split("_")); // 運行報錯
在非 “嚴格模式” 下,上述 TS 代碼編譯無誤,但是真正拿到頁面去運行編譯結果時,出現錯誤。
那怎么辦呢?要相信 TS 強大的類型系統,只需一項配置,就能將編譯切換成 “嚴格模式”:
// 在配置文件 tsconfig.json 中增加一項 "compilerOptions": { // ... "strictNullChecks": true },
再次執行編譯,就會出現錯誤提示信息:
error TS2322: Type "undefined[]" is not assignable to type "string[]".
TypeScript 官方教程鼓勵盡可能地使用 --strictNullChecks,因此這里也強烈建議配置該屬性再進行編譯,這樣能很好的發揮 TS 類型檢查的作用。
網開一面和漏網之魚TS 編譯通過指的是類型檢查符合類型系統的規則,運行 OK 則是編譯后的 JS 本身執行無誤。編譯通過,不等于運行OK,即使在 “嚴格模式” 下也是這樣的,所以千萬別以為編譯通過了就完事了。
以 Any 類型為例,在 --strictNullChecks 模式下:
// TS 代碼 let anyThing: any = "hello"; console.log(anyThing.myName); // 編譯后的 ES6 let anyThing = "hello"; console.log(anyThing.setName("world"));
很顯然,編譯后的 anyThing.setName("world") 會運行報錯。
當然, Any 類型略有點特殊,因為它可以當做是 TS 平滑退化到 JS 的一個類型,官網教程也有這樣解說:
在對現有代碼進行改寫的時候,any類型是十分有用的,它允許你在編譯時可選擇地包含或移除類型檢查。
那問題又回來了,是否除了 Any 類型,其他編譯OK,代碼就運行無錯呢?鑒于筆者正在入門,經驗有限,不敢給這個結論。但無論如何,類型檢查是可以排除大部分錯誤的。
最后,編譯的時候,盡量選擇編譯成 ES6 (前提是項目是用 ES6 寫的)。配置是:
"compilerOptions": { "target": "es6" // "es5" }只有一條規則
TS “冒號注釋” ——就這一條規則,貫穿始終。在函數的類型聲明中,繼續來鞏固這條規則的寫法。
類型聲明只對變量負責,對于函數,需考察輸入——函數參數(也是變量)、輸出——函數返回值兩個要素。
因為函數的特殊結構,所有 “冒號注釋” 規則的寫法要特別了解下:
// 聲明函數 function add(x: number, y: number): number { return x + y; } // 函數直接量 let myAdd = function(x: number, y: number): number { return x + y; };
可以看到,參數的 “冒號注釋” 和一般變量沒有任何差別。倒是函數輸出類型注釋有點特別——試想,: number 緊隨函數名之后或者 function 關鍵字之后,是不是容易被誤解為函數名的一部分?是不是對編譯引擎不太友好?從這個角度看,注釋置于) 之后最為合理。
對了,一個疑問一直從頭保留到現在:要是一個變量是 function 類型,那類型注釋怎么寫,又不能拿 function 關鍵字去做類型注釋?
let myAdd: (x: number, y: number) => number = function(x: number, y: number): number { return x + y; };
其中等號前邊的 : (x: number, y: number) => number 就代表了函數類型。它仍然在結構上符合 “冒號注釋” 的規則,只不過冒號后邊是一串表達式。這樣的結構有點像 Python 中的推導式的概念。
好了,補上這一塊重要的缺漏,本文就完成了所有基本類型的類型聲明的解釋。憑借一條規則,希望在 TS 學習上暢通無阻的敲代碼~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/89542.html
摘要:靜態屬性靜態方法目前支持靜態方法表示,類屬性及靜態屬性目前作為提案還未正式成為標準。在中,抽象類不能用來實例化對象,主要做為其它派生類的基類使用。不同于接口,抽象類可以包含成員的實現細節。中也是這樣規定的抽象類不允許直接被實例化。 嘗試重寫 在此之前,通過《JavaScript => TypeScript 入門》已經掌握了類型聲明的寫法。原以為憑著那一條無往不利的規則,就可以開開心心的...
摘要:前言這個輪子已經有很多人造過了,為了不重復造輪子,我將本項目以三階段實現大家可以在中的查看純前端后端前端后端前端希望能給大家一個漸進學習的經驗。 前言 Vue+Socket.io這個輪子已經有很多人造過了,為了不重復造輪子,我將本項目以三階段實現(大家可以在github中的Releases查看): 純前端(Vuex) 后端+前端(JavaScript) 后端+前端(TypeScrip...
先為大家介紹在vue項目中 jsconfig.json 官方說明:當您在工作空間中有一個定義項目上下文的jsconfig.json文件時,JavaScript體驗會得到改進。 概述 目錄中存在tsconfig.json文件表明該目錄是 TypeScript 項目的根目錄。該tsconfig.json文件指定編譯項目所需的根文件和編譯器選項。 JavaScript 項目可以使用jscon...
摘要:眾所周知,是弱類型的語言。因此在一些不注意的地方容易犯錯誤。通過得到這兩個值,是字符串類型的數字,很顯然返回之前已經了。反思雖然寫的是弱類型的,但是在有明確類型的情況下,最好還是轉換成對應的類型進行比較。 眾所周知,js是弱類型的語言。因此在一些不注意的地方容易犯錯誤。在此記錄一下前幾天寫代碼的時候,判斷兩個值相比較的結果來進行下一步的操作。通過ajax得到這兩個值,是字符串類型的數字...
摘要:入門,第一個這是一門很新的語言,年前后正式公布,算起來是比較年輕的編程語言了,更重要的是它是面向程序員的函數式編程語言,它的代碼運行在之上。它通過編輯類工具,帶來了先進的編輯體驗,增強了語言服務。 showImg(https://segmentfault.com/img/bV1xdq?w=900&h=385); 新的一年不知不覺已經到來了,總結過去的 2017,相信小伙們一定有很多收獲...
閱讀 1354·2021-09-10 10:51
閱讀 2829·2019-08-30 15:54
閱讀 3367·2019-08-29 17:11
閱讀 926·2019-08-29 16:44
閱讀 1390·2019-08-29 13:47
閱讀 1085·2019-08-29 13:47
閱讀 1485·2019-08-29 12:23
閱讀 1037·2019-08-28 18:18