做者:Dr. Axel Rauschmayer翻譯:瘋狂的技術宅html
原文:https://2ality.com/2020/02/un...前端
未經容許嚴禁轉載git
TypeScript中的類型是什麼?本文中描述了兩種有助於理解它們的觀點。程序員
如下三個問題對於理解類型如何工做很是重要,而且須要從兩個角度分別回答。github
myVariable
具備 MyType
類型是什麼意思?let myVariable: MyType = /*...*/;
SourceType
是否能夠分配給 TargetType
?let source: SourceType = /*...*/; let target: TargetType = source;
TypeUnion
是如何從 Type1
,Type2
和 Type3
派生的?type TypeUnion = Type1 | Type2 | Type3;
從這個角度來看,類型是一組值:面試
myVariable
的類型爲 MyType
,則意味着全部能夠分配給 myVariable
的值都必須是 MyType
集合的元素。SourceType
可分配給 TargetType
,SourceType
是 TargetType
的子集。結果全部能被 SourceType
接受的值也被 TargetType
接受。Type1
、Type2
和 Type3
的類型聯合是定義它們集合的集合理論 union。從這個角度來看,咱們不關心值自己以及在執行代碼時它們是如何流動的。相反,咱們採起了更加靜態的觀點:typescript
類型關係分配兼容性定義何時把源類型 S
分配給目標類型 T
:segmentfault
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