您好,登錄后才能下訂單哦!
小編給大家分享一下TypeScript常見類型有哪些,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
類型可以出現在很多地方,不僅僅是在類型注解 (type annotations)中。我們不僅要學習類型本身,也要學習在什么地方使用這些類型產生新的結構。
我們先復習下最基本和常見的類型,這些是構建更復雜類型的基礎。
string
,number
和 boolean
(The primitives)
JavaScript 有三個非常常用的原始類型:string
,number
和 boolean
,每一個類型在 TypeScript 中都有對應的類型。他們的名字跟你在 JavaScript 中使用 typeof
操作符得到的結果是一樣的。
string
表示字符串,比如 "Hello, world"
number
表示數字,比如 42,JavaScript 中沒有 int
或者 float
,所有的數字,類型都是 number
boolean
表示布爾值,其實也就兩個值: true
和 false
類型名 String
,Number
和 Boolean
(首字母大寫)也是合法的,但它們是一些非常少見的特殊內置類型。所以類型總是使用 string
,number
或者 boolean
。
聲明一個類似于 [1, 2, 3]
的數組類型,你需要用到語法 number[]
。這個語法可以適用于任何類型(舉個例子,string[]
表示一個字符串數組)。你也可能看到這種寫法 Array<number>
,是一樣的。我們會在泛型章節為大家介紹 T<U>
語法。
TypeScript 有一個特殊的類型,any
,當你不希望一個值導致類型檢查錯誤的時候,就可以設置為 any
。
當一個值是 any
類型的時候,你可以獲取它的任意屬性 (也會被轉為 any
類型),或者像函數一樣調用它,把它賦值給一個任意類型的值,或者把任意類型的值賦值給它,再或者是其他語法正確的操作,都可以:
let obj: any = { x: 0 }; // None of the following lines of code will throw compiler errors. // Using `any` disables all further type checking, and it is assumed // you know the environment better than TypeScript. obj.foo(); obj(); obj.bar = 100; obj = "hello"; const n: number = obj;
當你不想寫一個長長的類型代碼,僅僅想讓 TypeScript 知道某段特定的代碼是沒有問題的,any
類型是很有用的。
如果你沒有指定一個類型,TypeScript 也不能從上下文推斷出它的類型,編譯器就會默認設置為 any
類型。
如果你總是想避免這種情況,畢竟 TypeScript 對 any 不做類型檢查,你可以開啟編譯項 noImplicitAny,當被隱式推斷為 any 時,TypeScript 就會報錯。
當你使用 const
、var
或 let
聲明一個變量時,你可以選擇性的添加一個類型注解,顯式指定變量的類型:
let myName: string = "Alice";
TypeScript 并不使用“在左邊進行類型聲明”的形式,比如 int x = 0
;類型注解往往跟在要被聲明類型的內容后面。
不過大部分時候,這不是必須的。因為 TypeScript 會自動推斷類型。舉個例子,變量的類型可以基于初始值進行推斷:
// No type annotation needed -- 'myName' inferred as type 'string' let myName = "Alice";
大部分時候,你不需要學習推斷的規則。如果你剛開始使用,嘗試盡可能少的使用類型注解。你也許會驚訝于,TypeScript 僅僅需要很少的內容就可以完全理解將要發生的事情。
函數是 JavaScript 傳遞數據的主要方法。TypeScript 允許你指定函數的輸入值和輸出值的類型。
當你聲明一個函數的時候,你可以在每個參數后面添加一個類型注解,聲明函數可以接受什么類型的參數。參數類型注解跟在參數名字后面:
// Parameter type annotation function greet(name: string) { console.log("Hello, " + name.toUpperCase() + "!!"); }
當參數有了類型注解的時候,TypeScript 便會檢查函數的實參:
// Would be a runtime error if executed! greet(42); // Argument of type 'number' is not assignable to parameter of type 'string'.
即便你對參數沒有做類型注解,TypeScript 依然會檢查傳入參數的數量是否正確
你也可以添加返回值的類型注解。返回值的類型注解跟在參數列表后面:
function getFavoriteNumber(): number { return 26; }
跟變量類型注解一樣,你也不需要總是添加返回值類型注解,TypeScript 會基于它的 return
語句推斷函數的返回類型。像這個例子中,類型注解寫和沒寫都是一樣的,但一些代碼庫會顯式指定返回值的類型,可能是因為需要編寫文檔,或者阻止意外修改,亦或者僅僅是個人喜好。
匿名函數有一點不同于函數聲明,當 TypeScript 知道一個匿名函數將被怎樣調用的時候,匿名函數的參數會被自動的指定類型。
這是一個例子:
// No type annotations here, but TypeScript can spot the bug const names = ["Alice", "Bob", "Eve"]; // Contextual typing for function names.forEach(function (s) { console.log(s.toUppercase()); // Property 'toUppercase' does not exist on type 'string'. Did you mean 'toUpperCase'? }); // Contextual typing also applies to arrow functions names.forEach((s) => { console.log(s.toUppercase()); // Property 'toUppercase' does not exist on type 'string'. Did you mean 'toUpperCase'? });
盡管參數 s
并沒有添加類型注解,但 TypeScript 根據 forEach
函數的類型,以及傳入的數組的類型,最后推斷出了 s
的類型。
這個過程被稱為上下文推斷(contextual typing),因為正是從函數出現的上下文中推斷出了它應該有的類型。
跟推斷規則一樣,你也不需要學習它是如何發生的,只要知道,它確實存在并幫助你省掉某些并不需要的注解。后面,我們還會看到更多這樣的例子,了解一個值出現的上下文是如何影響它的類型的。
除了原始類型,最常見的類型就是對象類型了。定義一個對象類型,我們只需要簡單的列出它的屬性和對應的類型。
舉個例子:
// The parameter's type annotation is an object type function printCoord(pt: { x: number; y: number }) { console.log("The coordinate's x value is " + pt.x); console.log("The coordinate's y value is " + pt.y); } printCoord({ x: 3, y: 7 });
這里,我們給參數添加了一個類型,該類型有兩個屬性, x
和 y
,兩個都是 number
類型。你可以使用 ,
或者 ;
分開屬性,最后一個屬性的分隔符加不加都行。
每個屬性對應的類型是可選的,如果你不指定,默認使用 any
類型。
對象類型可以指定一些甚至所有的屬性為可選的,你只需要在屬性名后添加一個 ?
:
function printName(obj: { first: string; last?: string }) { // ... } // Both OK printName({ first: "Bob" }); printName({ first: "Alice", last: "Alisson" });
在 JavaScript 中,如果你獲取一個不存在的屬性,你會得到一個 undefined
而不是一個運行時錯誤。因此,當你獲取一個可選屬性時,你需要在使用它前,先檢查一下是否是 undefined
。
function printName(obj: { first: string; last?: string }) { // Error - might crash if 'obj.last' wasn't provided! console.log(obj.last.toUpperCase()); // Object is possibly 'undefined'. if (obj.last !== undefined) { // OK console.log(obj.last.toUpperCase()); } // A safe alternative using modern JavaScript syntax: console.log(obj.last?.toUpperCase()); }
TypeScript 類型系統允許你使用一系列的操作符,基于已經存在的類型構建新的類型。現在我們知道如何編寫一些基礎的類型了,是時候把它們組合在一起了。
第一種組合類型的方式是使用聯合類型,一個聯合類型是由兩個或者更多類型組成的類型,表示值可能是這些類型中的任意一個。這其中每個類型都是聯合類型的成員(members)。
讓我們寫一個函數,用來處理字符串或者數字:
function printId(id: number | string) { console.log("Your ID is: " + id); } // OK printId(101); // OK printId("202"); // Error printId({ myID: 22342 }); // Argument of type '{ myID: number; }' is not assignable to parameter of type 'string | number'. // Type '{ myID: number; }' is not assignable to type 'number'.
提供一個符合聯合類型的值很容易,你只需要提供符合任意一個聯合成員類型的值即可。那么在你有了一個聯合類型的值后,你該怎樣使用它呢?
TypeScript 會要求你做的事情,必須對每個聯合的成員都是有效的。舉個例子,如果你有一個聯合類型 string | number
, 你不能使用只存在 string
上的方法:
function printId(id: number | string) { console.log(id.toUpperCase()); // Property 'toUpperCase' does not exist on type 'string | number'. // Property 'toUpperCase' does not exist on type 'number'. }
解決方案是用代碼收窄聯合類型,就像你在 JavaScript 沒有類型注解那樣使用。當 TypeScript 可以根據代碼的結構推斷出一個更加具體的類型時,類型收窄就會出現。
舉個例子,TypeScript 知道,對一個 string
類型的值使用 typeof
會返回字符串 "string"
:
function printId(id: number | string) { if (typeof id === "string") { // In this branch, id is of type 'string' console.log(id.toUpperCase()); } else { // Here, id is of type 'number' console.log(id); } }
再舉一個例子,使用函數,比如 Array.isArray
:
function welcomePeople(x: string[] | string) { if (Array.isArray(x)) { // Here: 'x' is 'string[]' console.log("Hello, " + x.join(" and ")); } else { // Here: 'x' is 'string' console.log("Welcome lone traveler " + x); } }
注意在 else
分支,我們并不需要做任何特殊的事情,如果 x
不是 string[]
,那么它一定是 string
.
有時候,如果聯合類型里的每個成員都有一個屬性,舉個例子,數字和字符串都有 slice
方法,你就可以直接使用這個屬性,而不用做類型收窄:
// Return type is inferred as number[] | string function getFirstThree(x: number[] | string) { return x.slice(0, 3); }
以上是“TypeScript常見類型有哪些”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。