類型
TypeScript的類型有很多,但是這裏不會逐一進行講解。下面列出來的幾種類型,有的你可能沒聽過、有的你可能沒用過、有的你可能用過但是不知道含義、有的你可能知道含義但是不能和其他類型區分···
Symbol
ES6 引入了一種新的原始數據類型 Symbol ,表示獨一無二的值,它是 JavaScript 語言的第七種數據類型。
使用 Symbol() 函數我們可以申明一個 Symbol 變量,注意不能使用 new 命令,因為它是原始數據類型;Symbol 函數也可以接受一個字符串作為參數,主要是方便當 Symbol 轉化為字符串時,比較容易區分,該傳入的參數在 ES2019 中支持通過 description 這個實例屬性來訪問。
Tuple(元組)
眾所周知,對象、數組、枚舉類型可以存放多個數據;但是,對象和枚舉存放的數據以key/value形式存在,不具有排序等特效,數組中存放的只能是同一類型數據;Tuple類型可以看做是對象類型和數組類型特點的結合:
- 數據有序;
- 存放不同類型數據;
在 JavaScript 中是沒有元組的,元組是 TypeScript 中特有的類型,其⼯作⽅式類似 於數組。 元組可⽤於定義有限數量的未命名屬性的類型。每個屬性都有⼀個關聯的類型。使⽤元組時,必須 提供每個屬性的值,可以通過索引訪問元素:
let tupleType: [string, boolean, number];
tupleType = ["hello", true, 2];
console.log(tupleType[0]); // hello
console.log(tupleType[1]); // true
console.log(tupleType[2]); //2
any(任意類型)
在 TypeScript 中,任何類型都可以被歸為 any 類型。這讓 any 類型成為了類型系統的頂級類型(也被 稱作全局超級類型)。
any 類型本質上是類型系統的⼀個避難所,這給了開發者很⼤的⾃由:TypeScript 允許我們 對 any 類型的值執⾏任何操作,包括賦值和被賦值,並且⽆需事先執⾏任何形式的檢查。⽐如:
let value: any;
// 被賦值
value = 'hello world';
value = true;
value = [];
value = {};
value = 0;
// 賦值給其他變量
let temp: number;
temp = value;
// 操作屬性/方法
value.toString();
value.length;
value();
- any可以為任何類型,所以默認變量上的任何屬性或者方法都可以找到一個類型(基礎類型/自定義類型)對應上,所以檢查沒有問題;
unknown(不知道什麼類型)
就像所有類型都可以賦值給 any ,所有類型也都可以賦值給 unknown 。這使得 unknown 成為 TypeScript 類型系統的另⼀種頂級類型(另⼀種是 any );
對 value 變量的所有賦值都被認為是類型正確的。但是,嘗試將類型為 unknown 的值賦值給其 他類型的變量時就會有意想不到的限制:
let value: unknown;
// 被賦值
value = 'hello world';
value = true;
value = [];
value = {};
value = 0;
// 賦值給其他變量
let temp: number; // Error:Type 'unknown' is not assignable to type 'number'.
temp = value;
let temp2: any;
temp2 = value; // Success
let temp3: unknown;
temp3 = value; // Success
let temp4: string[]; // Error:Type 'unknown' is not assignable to type 'string[]'
temp4 = value;
// 操作屬性/方法
value.toString(); // Error:Object is of type 'unknown'
value.length; // Error:Object is of type 'unknown'
value(); // Error:Object is of type 'unknown'
- unknown 類型只能被賦值給 any 類型和 unknown 類型本身:能夠保 存任意類型值的容器才能保存 unknown 類型的值。
- value 變量類型為 unknown ,進行檢查的時候無法確認變量類型,因此認為變量上的方法或者屬性都是不確定的,檢查不給通過。
void(沒有任何類型)
void可以理解為和any正好相反,表示沒有任何類型,void一般用於一個函數沒用返回值時。當給一個變量定義為void類型時是沒有任何作用,變量的值只能是undefined
let value:void;
value = 0; // Error:Type 'number' is not assignable to type 'void'.
value = undefined; // Success
null(空值類型)和 undefined(未定義類型)
TypeScript ⾥, undefined 和 null 兩者有各⾃的類型的值分別為 undefined 和 null ,並且只能是 undefined 和 null:
let value:null;
value = undefined; // Error:Type 'undefined' is not assignable to type 'null'
value = null; //Success
value = 1; // Error:Type '1' is not assignable to type 'null'
let value:undefined;
value = undefined; //Success
value = null; // Error:Type 'null' is not assignable to type 'undefined'
value = 1; // Error:Type '1' is not assignable to type 'undefined'
Object、object和{}(對象類型)
# TypeScript中如何使用Object、object和{}?
Never
never 類型表示不存在的值的類型。never 類型用於:
- 拋出異常
- 不會有返回值的函數表達式或箭頭函數表達式的返回值類型(無終點,一直執行下去!)。
function error(msg: string)msgever {
throw new Error(msg);
}
function loop(): never {
while (true) {
// 一直執行下去
}
}
使⽤ never 避免出現新增了聯合類型沒有對應的實現,⽬的就是寫出類型絕對安全的代碼;可以利⽤ never 類型的特性對變量類型全⾯性檢查:
// 定義type a為string或者number類型
type a = string | number;
// 方法checkWithNever用來檢測參數是否是type a,
function checkWithNever(foo: a) {
if (typeof foo === "string") {
// 這⾥執行 string 類型的操作
} else if (typeof foo === "number") {
// 這⾥執行 number 類型的操作
} else {
// 在這⾥是 never用來接收非type a的類型,並且會在編譯時報錯
const check: never = foo;
}
}
// 重寫 type a類型,但是沒有修改checkWithNever,導致boolean 類型,⽆法賦值給 never 類型,執行後編譯報錯
type a = string | number | boolean;
const c: a = true;
checkWithNever(c);
// Type 'boolean' is not assignable to type 'never'.
// 'check' is declared but its value is never read.