做者:Dr. Axel Rauschmayerhtml
翻譯:瘋狂的技術宅前端
原文:2ality.com/2020/02/und…git
未經容許嚴禁轉載github
TypeScript中的類型是什麼?本文中描述了兩種有助於理解它們的觀點。typescript
如下三個問題對於理解類型如何工做很是重要,而且須要從兩個角度分別回答。前端工程化
myVariable
具備 MyType
類型是什麼意思?let myVariable: MyType = /*...*/;
複製代碼
SourceType
是否能夠分配給 TargetType
?let source: SourceType = /*...*/;
let target: TargetType = source;
複製代碼
TypeUnion
是如何從 Type1
,Type2
和 Type3
派生的?type TypeUnion = Type1 | Type2 | Type3;
複製代碼
從這個角度來看,類型是一組值:app
myVariable
的類型爲 MyType
,則意味着全部能夠分配給 myVariable
的值都必須是 MyType
集合的元素。SourceType
可分配給 TargetType
,SourceType
是 TargetType
的子集。結果全部能被 SourceType
接受的值也被 TargetType
接受。Type1
、Type2
和 Type3
的類型聯合是定義它們集合的集合理論 union。從這個角度來看,咱們不關心值自己以及在執行代碼時它們是如何流動的。相反,咱們採起了更加靜態的觀點:編輯器
S
分配給目標類型 T
:
S
和 T
是相同的類型。S
或 T
是 any
類型。
讓咱們考慮如下問題:函數
myVariable
的靜態類型分配給 MyType
,則 myVariable
的類型爲 MyType
。SourceType
是兼容分配的,則能夠將它們分配給 TargetType
。TypeScript 類型系統的一個有趣特徵是,同一變量在不一樣位置能夠具備不一樣的靜態類型:工具
const arr = [];
// %inferred-type: any[]
arr;
arr.push(123);
// %inferred-type: number[]
arr;
arr.push('abc');
// %inferred-type: (string | number)[]
arr;
複製代碼
靜態類型系統的職責之一是肯定兩種靜態類型是否兼容:
U
(例如,經過函數調用提供)T
(在函數定義中指定)這一般意味着檢查 U
是否爲 T
的子類型。大體有兩種檢查方法:
U
具備 T
的全部部分(可能還有其餘),而且 U
的每一個部分具備 T
的相應部分的子類型,則類型 U
是另外一種類型 T
的子類型。如下代碼在名義類型系統中會產生類型錯誤(A 行),但在 TypeScript 的結構類型系統中是合法的,由於類 A
和類 B
具備相同的結構:
class A {
name = 'A';
}
class B {
name = 'B';
}
const someVariable: A = new B(); // (A)
複製代碼
TypeScript 的 interface 在結構上也能夠正常工做 —— 沒必要爲了匹配而實現它們:
interface Point {
x: number;
y: number;
}
const point: Point = {x: 1, y: 2}; // OK
複製代碼