6種基本數據類型數組
Boolean
Number
String
Symbol
undefined
null
3種引用類型tomcat
Array Function Object
TS在ES6基礎上,又新增瞭如下數據類型less
void any never 元組 枚舉 高級類型
除此以外,TS還有不少類型的高級使用技巧編輯器
TS能夠經過類型註解對變量類型進行約束 TS和JS最主要的區別:變量的數據類型不可改變 語法: 變量/函數 : type 如: let hello : string = 'Hello TypeScript'
let bl: boolean = true let num: number = 123 let str: string = "123"
使用類型註解對變量進行類型約束後,再進行不恰當的賦值就會報錯函數
在 TypeScript 中,數組類型有多種定義方式,主要有一下三種定義方法:
ui
一、「類型 + 方括號」表示法spa
let tsArray: number[] = [1,1,2,3,4]
數組中的項中不容許出現其餘類型
rest
let fibonacci: number[] = [1, '1', 2, 3, 5]; //報錯
上例中,
code[1, '1', 2, 3, 5]
的類型被推斷爲 (number | string)[]
,這是聯合類型和數組的結合。
對象 數組的一些方法的參數也會根據數組在定義時約定的類型進行限制:
let fibonacci: number[] = [0, 1, 2, 3, 5]; fibonacci.push('6'); // index.ts(2,16): error TS2345: Argument of type 'string' is not assignable to parameter of type 'number'.
上例中,
push
方法只容許傳入 number
類型的參數,可是卻傳了一個 string
類型的參數,因此報錯了。
二、數組泛型
使用數組泛型(Array Generic)
Array<elemType>
來表示數組:
let arrType: Array<number> = [0, 1, 2, 3, 5]; let arrType1: Array<string> = ['0', '1', '2', '3', '5']; let arrType2: Array<any> = [1, '1', 2, 's', true];
三、
用接口表示數組
interface Person{ name: string; age: number; } interface NumberArray { [index:number]: Person; } let arrType3: NumberArray = [{name:'張三',age: 20}] let arrType4:Array<Person> = [{name:'張三',age: 20}] let arrType5:Person[] = [{name:'張三',age: 20}]
NumberArray
表示:只要 index
的類型是 number
,那麼值的結構類型必須是符合Person接口。
類數組(特別注意)
類數組(Array-like Object)不是數組類型,好比 arguments
:
function sum() { let args: number[] = arguments; } // index.ts(2,7): error TS2322: Type 'IArguments' is not assignable to type 'number[]'. // Property 'push' is missing in type 'IArguments'.
事實上常見的類數組都有本身的接口定義,如 IArguments
, NodeList
, HTMLCollection
等:
function sum() { let args: IArguments = arguments; }
是一種限制數組的元素類型和個數的數組
let tuple: [number, string] = [0, '1']
此時,若是改變數組的元素類型或添加元素數量,編輯器都會報錯:
let tuple: [number, string] = [0, 1] //Type 'number' is not assignable to type 'string'. let tuple: [number, string] = [0, '1', '2'] //報錯: Type '[number, string, string]' is not assignable to type '[number, string]'. Types of property 'length' are incompatible. Type '3' is not assignable to type '2'.
雖然元組限制了數組元素的類型和數量,過多的元素聲明會報錯
但TS容許向元組中使用數組的push方法插入新元素(但不容許訪問)
let tuple: [number, string] = [0, '1'] tuple.push(2) console.log("tuple.push(2)", tuple) // tuple.push(2) (3) [0, "1", 2]
但不容許訪問:
tuple.push(2) // 可越界添加 tuple[2] // 不可越界訪問 //報錯: //Tuple type '[number, string]' of length '2' has no element at index '2'.
在 JavaScript 中,有兩種常見的定義函數的方式——函數聲明(Function Declaration)和函數表達式(Function Expression):
// 函數聲明(Function Declaration) function sum(x, y) { return x + y; } // 函數表達式(Function Expression) let mySum = function (x, y) { return x + y; };
一個函數有輸入和輸出,要在 TypeScript 中對其進行約束,須要把輸入和輸出都考慮到,其中函數聲明的類型定義較簡單:
function sum(x:number,y:number):number{ return x+y }
注意,輸入多餘的或者少於要求的參數,是不被容許的
sum(1, 2, 3); // index.ts(4,1): error TS2346: Supplied parameters do not match any signature of call target.
sum(1); // index.ts(4,1): error TS2346: Supplied parameters do not match any signature of call target.
若是要咱們如今寫一個對函數表達式(Function Expression)的定義,可能會寫成這樣
let mySun = function(x:number,y:number):number{ return x + y }
這是能夠經過編譯的,不過事實上,上面的代碼只對等號右側的匿名函數進行了類型定義,而等號左邊的 mySum
,是經過賦值操做進行類型推論而推斷出來的。若是須要咱們手動給 mySum
添加類型,則應該是這樣:
let mySum(x:number,y:number)=>number = function(x:number,y:number):number{ return x+y}
注意不要混淆了 TypeScript 中的 =>
和 ES6 中的 =>
。
在 TypeScript 的類型定義中,=>
用來表示函數的定義,左邊是輸入類型,須要用括號括起來,右邊是輸出類型。
在 ES6 中,=>
叫作箭頭函數,應用十分普遍,
咱們也可使用接口的方式來定義一個函數須要符合的形狀:
interface SearchFunc{ (source:string,subString:string):boolean } let mySearch:SearchFunc; mySearch = function(source: string,subString:string){ return source.search(subString) !== -1 }
前面提到,輸入多餘的(或者少於要求的)參數,是不容許的。那麼如何定義可選的參數呢?
與接口中的可選屬性相似,咱們用 ?
表示可選的參數:
function buildName(firstName: string, lastName?: string) { if (lastName) { return firstName + ' ' + lastName; } else { return firstName; } } let tomcat = buildName('Tom', 'Cat'); let tom = buildName('Tom');
注意:可選參數必須接在必需參數後面。換句話說,可選參數後面不容許再出現必須參數了
在 ES6 中,咱們容許給函數的參數添加默認值,TypeScript 會將添加了默認值的參數識別爲可選參數:
function buildName(firstName:string,lastName:string='Cat'){ return firstName + ' ' + lastName; } let tomcat = buildName('Tom', 'Cat'); let tom = buildName('Tom');
此時就不受「可選參數必須接在必需參數後面」的限制了:
function buildName(firstName: string = 'Tom', lastName: string) { return firstName + ' ' + lastName; } let tomcat = buildName('Tom', 'Cat'); let cat = buildName(undefined, 'Cat');
ES6 中,可使用 ...rest
的方式獲取函數中的剩餘參數(rest 參數):
function push(array,...items){ items.forEach(function(item){ array.push(item) }) } let a = []; push(a,1,2,3)
事實上,items
是一個數組。因此咱們能夠用數組的類型來定義它:
function push(array:any[],...items:any[]){
items.forEach(function(item){
array.push(item);
})
}
let a = []
push(a,1,2,3)
注意:rest 參數只能是最後一個參數
重載容許一個函數接受不一樣數量或類型的參數時,做出不一樣的處理。
好比,咱們須要實現一個函數 reverse
,輸入數字 123
的時候,輸出反轉的數字 321
,輸入字符串 'hello'
的時候,輸出反轉的字符串 'olleh'
。
利用聯合類型,咱們能夠這麼實現:
function reverse(x: number | string): number | string { if (typeof x === 'number') { return Number(x.toString().split('').reverse().join('')); } else if (typeof x === 'string') { return x.split('').reverse().join(''); } }
然而這樣有一個缺點,就是不可以精確的表達,輸入爲數字的時候,輸出也應該爲數字,輸入爲字符串的時候,輸出也應該爲字符串。
這時,咱們可使用重載定義多個 reverse
的函數類型:
function reverse(x: number): number; function reverse(x: string): string; function reverse(x: number | string): number | string { if (typeof x === 'number') { return Number(x.toString().split('').reverse().join('')); } else if (typeof x === 'string') { return x.split('').reverse().join(''); } }
上例中,咱們重複定義了屢次函數 reverse
,前幾回都是函數定義,最後一次是函數實現。在編輯器的代碼提示中,能夠正確的看到前兩個提示。
注意:TypeScript 會優先從最前面的函數定義開始匹配,因此多個函數定義若是有包含關係,須要優先把精確的定義寫在前面。
在JS中,能夠任意修改對象屬性,TS中不容許
let obj: object = {x: 'a', y: 'b'} obj.x = 3 // Property 'x' does not exist on type 'object'.
這是由於,僅聲明瞭對象obj的類型註解是object, 並無爲對象內部的具體屬性(屬性名)和類型作限制
let obj: {x: string, y: string} = {x: 'a', y: 'b'}
obj.x = 'c'
還可使用接口的形式來規範對象,接口會在下一篇隨筆介紹。
具備惟一的值 能夠顯式聲明,也可直接建立
let symbol1: Symbol = Symbol() // 顯示聲明 let symbol2 = Symbol() // 直接建立 // 驗證:是不是同一個對象 console.log(symbol1 === symbol2) // fasle
let udf: undefined = undefined let nu: null = null
let undf: undefined = 1 // Type '1' is not assignable to type 'undefined'.
// 驗證:undefined和null也能被賦值給任何其餘類型 let num1: number = undefined // Type 'undefined' is not assignable to type 'number'. let num2: number = null // Type 'null' is not assignable to type 'number'.
在TS中,undefined和null是任何類型的子類型,因此能夠被賦值給其餘類型
設置容許被賦值爲其餘類型
打開tsconfig.js,將strictNullChecks = false(默認true)
let num3: number | undefined | null = 111
在js中,void操做符可使任何一個表達式返回undefined
void 0 // 將返回undefined
在TS中,void類型表示沒有返回值,沒有返回值的函數,他的類型就是void類型
// void let voidFunc = () => {}
any:若是不指定TS的變量類型,默認爲any類型,能夠賦值爲任何類型
let x x = 1 // 整型 x = [] // 數組 x = () => {} // 函數
不建議使用any類型,將失去使用ts的意義
never:永遠不會有返回值的類型
1,函數拋出異常,永遠不會有返回值,類型爲never
// 函數拋出異常,永遠不會有返回值,類型爲never let error = () => { throw new Error('error') }
2,死循環函數永遠沒有返回值,類型爲never
// 死循環函數永遠沒有返回值,類型爲never let endless = () => { while(true) {} }