做者:Marius Schulzhtml
譯者:前端小智前端
來源:mariusschulz.com/git
點贊再看,養成習慣
es6
本文 GitHub:github.com/qq449245884… 上已經收錄,更多往期高贊文章的分類,也整理了不少個人文檔,和教程資料。歡迎Star和完善,你們面試能夠參照考點複習,但願咱們一塊兒有點東西。github
我的專欄 ES6 深刻淺出已上線,深刻ES6 ,經過案例學習掌握 ES6 中新特性一些使用技巧及原理,持續更新中,←點擊可訂閱。面試
系列文章以下:typescript
【TypeScript 演化史 -- 1】non-nullable 的類型數據結構
【TypeScript 演化史 -- 2】基於控制流的類型分析 和 只讀屬性app
【TypeScript 演化史 -- 3】標記聯合類型 與 never 類型async
【TypeScript 演化史 -- 4】更多的字面量類型 與 內置類型聲明
【TypeScript 演化史 -- 5】將 async/await 編譯到 ES3/ES5 (外部幫助庫)
【TypeScript 演化史 -- 6】對象擴展運算符和 rest 運算符及 keyof 和查找類型
【TypeScript 演化史 -- 7】映射類型和更好的字面量類型推斷
【TypeScript 演化史 -- 8】字面量類型擴展 和 無類型導入
TypeScript 2.2 引入了一個新的 object
類型。它表示任何非基本類型。如下是 JS 的基本類型:
上述之外類型都被認爲是非基本類型,能夠用新的 object
類型表示:
// 全部基本類型
type Primitive =
| string
| boolean
| number
| bigint
| symbol
| null
| undefined;
// 全部非基本類型
type NonPrimitive = object;
複製代碼
隨着 TypeScript 2.2 的發佈,標準庫的類型聲明已經更新,以使用新的 object
類型。例如,object.create()
和 object.setprototypeof()
方法現的參數類型是 object | null
interface ObjectConstructor {
create(o: object | null): any;
setPrototypeOf(o: any, proto: object | null): any;
// ...
}
複製代碼
將基本類型的值做爲參數傳遞給 Object.setPrototypeOf()
或 Object.create()
會致使在運行時拋出類型錯誤。TypeScript 如今捕獲這些錯誤並在編譯時提示錯誤:
const proto = {};
Object.create(proto); // OK
Object.create(null); // OK
Object.create(undefined); // Error
Object.create(1337); // Error
Object.create(true); // Error
Object.create("oops"); // Error
複製代碼
object
類型的另外一個用例是 ES6 引入的 WeakMap
數據結構。它的鍵必須是對象,不能是基本類型值:
interface WeakMap<K extends object, V> {
delete(key: K): boolean;
get(key: K): V | undefined;
has(key: K): boolean;
set(key: K, value: V): this;
}
複製代碼
object
vs Object
vs {}
可能使人困惑的是,TypeScript定義了幾個具備類似名稱但表示不一樣概念的類型:
上面已經講過 object
類型,如今來看看 Object
和 {}
。
TypeScript 定義了另外一個與新 object
類型幾乎同名的類型,那就是 Object
類型。object
(小寫)表示全部非基本類型,而 Object
(大寫)描述全部 JS 對象共有的功能。例如,它包括 toString()
和 hasOwnProperty()
方法。
在TypeScript附帶的lib.es6.d.ts
文件中,Object
類型定義以下:
interface Object {
// ...
/** Returns a string representation of an object. */
toString(): string;
/** Returns a date converted to a string using the current locale. */
toLocaleString(): string;
/** Returns the primitive value of the specified object. */
valueOf(): Object;
/**
* Determines whether an object has a property with the specified name.
* @param v A property name.
*/
hasOwnProperty(v: string): boolean;
/**
* Determines whether an object exists in another object's prototype chain.
* @param v Another object whose prototype chain is to be checked.
*/
isPrototypeOf(v: Object): boolean;
/**
* Determines whether a specified property is enumerable.
* @param v A property name.
*/
propertyIsEnumerable(v: string): boolean;
}
複製代碼
{}
還有另外一種類型與之很是類似:{}
,即空類型。它描述了一個自己沒有成員的對象。當我們試圖訪問此類對象上的任意屬性時,TypeScript 會提示編譯時錯誤
// Type {}
const obj = {};
// Error: 類型「{}」上不存在屬性「prop」
obj.prop = "value";
複製代碼
可是,仍然可使用在 Object
類型上定義的全部屬性和方法,這些屬性和方法經過JS 的原型鏈調用:
// Type {}
const obj = {};
// "[object Object]"
obj.toString();
複製代碼
在 TypeScript 2.2 以前,若是想訪問帶有字符串索引簽名的類型的任意屬性,就必須使用[]
符號,但不容許使用.
符號訪問
interface Dictionary<T> {
[key: string]: T;
}
const portNumbers: Dictionary<number> = {};
// OK
portNumbers["http"] = 80;
// Error: Property 'http' does not exist on type 'Dictionary<number>'.
portNumbers.http = 80;
複製代碼
TypeScript 2.2 取消了這個限制。如今可使用 []
或 .
符號訪問屬性。在許多狀況下,再也不須要像這樣使人不快的變通方法:
// 笨拙的方式
(portNumbers as any).http = 80;
複製代碼
請注意,類型必須定義顯式字符串索引簽名,以便用.
符號訪問對任意屬性都是類型正確的。在類型使用上使用.
符號訪問未知屬性仍然是一個錯誤,所以,對於如下代碼,TypeScript 2.2 仍然會給出一個編譯時錯誤:
const portNumbers = {};
// OK
portNumbers["http"] = 80;
// Error: Property 'http' does not exist on type '{}'.
portNumbers.http = 80;
複製代碼
若是仔細想一想,就會發現這頗有意義:若是 TypeScript 沒有爲這段代碼提供一個錯誤,那麼就沒有對拼寫錯誤的屬性名的保護。在 JS 中訪問屬性時,大多數時候將使用點
表示法,但也可使用括號表示法做爲轉義。
有了這個較鬆的限制,對於經常使用JS 開發的人員來講更容易使用。若是我們要將現有的 JS 代碼基礎遷移到 TypeScript,這尤爲有用。給定適當的字符串索引簽名,在這些狀況下,就會得到更少的類型錯誤,而且再也不須要使用類型註釋註釋點屬性訪問,這只是爲了讓編譯器經過。
原文:
乾貨系列文章彙總以下,以爲不錯點個Star,歡迎 加羣 互相學習。
我是小智,公衆號「大遷世界」做者,對前端技術保持學習愛好者。我會常常分享本身所學所看的乾貨,在進階的路上,共勉!
關注公衆號,後臺回覆福利,便可看到福利,你懂的。