建立一個數組很簡單:ios
const arr = [1];
複製代碼
此時 TypeScript 將會推斷 arr
類型爲 number[]
:git
arr.push('1'); // Error
複製代碼
當數組元素具備其它類型時,能夠經過類型註解的方式:github
const arr: Array<string | number> = [1];
arr.push('1'); // OK
arr.push(true); // Error
複製代碼
或者你也能夠經過可選元組的方式:typescript
const arr: [number, string?] = [1]; // arr 的成員類型能夠是: number, string, undefined
arr.push('1'); // OK
arr.push(true); // Error
複製代碼
使用元組形式,還能提供指定位置的類型檢查:axios
arr[0] = '1'; // Error
arr[1] = 1; // Error
複製代碼
一般,咱們使用 Promise.all
並行發出多個請求:數組
interface A {
name: string;
}
interface B {
age: number;
}
const [{ data: a }, { data: b }] = await Promise.all([
axios.get<A>('http://some.1'),
axios.get<B>('http://some.2')
])
複製代碼
此時,TypeScript 能推出 a
的類型是 A
, b
的類型是 B
。安全
如今,稍做改變:當知足特定條件時,才發出第二個請求:函數
// 使用類型註解
const requestList: [Promise<AxiosResponse<A>>, Promise<AxiosResponse<B>>?]
= [axios.get<A>('http://some.1')];
if (flag) {
requestList[1] = (axios.get<B>('http://some.2'));
};
const [ { data: a }, response ] = await Promise.all(requestList);
複製代碼
咱們指望它會如預想時那樣工做,但是事與願違,Promise.all(requestList)
,會出現類型兼容性的報錯,在這個 Issues 裏,描述了相同的問題。ui
如今,你能夠經過斷言的方式,來讓程序正常運做:spa
const requestList: any[] = [axios.get<A>('http://some.1')]; // 設置爲 any[] 類型
if (flag) {
requestList[1] = (axios.get<B>('http://some.2'));
}
const [
{ data: a },
response
] = await Promise.all(requestList) as [AxiosResponse<A>, AxiosResponse<B>?] // 類型安全
複製代碼
在 JavaScript 基礎上,TypeScript 擴展了一系列字面量類型,用來確保類型的準確性。
如建立一個字符串字面量:
const a = 'hello'; // a 的類型是 'hello'
a = 'world'; // Error
複製代碼
或者你也能夠:
let a: 'hello' = 'hello'; // a 的類型是 'hello'
a = 'world'; // Error
複製代碼
其它數據類型與此類似。
你也能夠定義交叉類型與聯合類型的字面量:
interface A {
name: string;
}
interface B {
name: string;
age: number;
}
type C = A | B;
type D = A & B;
複製代碼
對於對象字面量的類型,TypeScript 有一個被稱之爲 「Freshness 」的概念,它也被稱爲更嚴格的對象字面量檢查,以下例子:
let someThing: { name: string };
someThing = { name: 'hello' }; // ok
someThing = { name: 'hello', age: 123 }; // Error, 對象字面量只能指定已知屬性, { name: string } 類型中不存在 age 屬性
let otherThing = { name: 'hello', age: 123 };
someThing = otherThing; // ok
複製代碼
TypeScript 認爲建立的每一個對象字面量都是 「 fresh 」 狀態;當一個 「 fresh 」 對象字面量賦值給一個變量時,若是對象的類型與變量類型不兼容時,會出現報錯(如上例子中 someThine = { name: 'hello', age: 123 };
的錯誤);當對象字面量的類型變寬,對象字面量的 「 fresh 」 狀態會消失(如上例子中 someThing = otherThing;
,賦值之後,someThing
的類型變寬)。
一個更實際的用例以下:
function logName(something: { name: string }) {
console.log(something.name);
}
const obj = {
name: 'matt',
job: 'being awesome'
}
logName(obj); // ok
logName({ name: 'matt' }); // ok
logName({ nama: 'matt' }); // Error: nama 屬性在 { name: string } 屬性中不存在。
logName({ name: 'matt', job: 'being awesome' }); // Error: 對象字面量只能指定已知屬性,`job` 屬性在這裏並不存在。
複製代碼
基本原理與上文中類似,當想用更嚴格的類型檢查時,能夠傳一個具備 fresh 狀態的對象字面量(如 logName({ name: 'matt', job: 'being awesome' });
)。當你想多傳一些屬性至函數,能夠將對象字面量賦值至一個新變量,而後再傳至函數(如 logName(obj)
)。或者你也能夠經過給函數形參添加多餘類型的方式 function logName(someThing: { name: string; [key: string]: string })
。