TypeScript——02——TS基本數據類型介紹和使用

一,TS的數據類型

ES6的數據類型:

6種基本數據類型數組

Boolean
	Number
	String
	Symbol
	undefined
	null

3種引用類型tomcat

Array
	Function
	Object
TS的數據類型:

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];
//報錯

  上例中,[1, '1', 2, 3, 5] 的類型被推斷爲 (number | string)[],這是聯合類型和數組的結合。code

 數組的一些方法的參數也會根據數組在定義時約定的類型進行限制:對象

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'.

  事實上常見的類數組都有本身的接口定義,如 IArgumentsNodeListHTMLCollection 等:

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'

還可使用接口的形式來規範對象,接口會在下一篇隨筆介紹。


八,Symbol

具備惟一的值
	能夠顯式聲明,也可直接建立
let symbol1: Symbol = Symbol()  // 顯示聲明
let symbol2 = Symbol()  // 直接建立

// 驗證:是不是同一個對象
console.log(symbol1 === symbol2)    // fasle

 


九,undefined 和 null

let udf: undefined = undefined
let nu: null = null
一旦聲明瞭undefined,就不能再被賦值爲任何其餘的數據類型了:
let undf: undefined = 1 
// Type '1' is not assignable to type 'undefined'.
默認狀況下,undefined和null也不能被賦值給任何其餘類型:
// 驗證: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'.
容許undefined和null被賦值其餘類型:
在TS中,undefined和null是任何類型的子類型,因此能夠被賦值給其餘類型

設置容許被賦值爲其餘類型

打開tsconfig.js,將strictNullChecks = false(默認true)

nullcheck

在不修改此配置的狀況下,實現對undefined和null的賦值,可以使用聯合類型
let num3: number | undefined | null = 111

 


十,void

在js中,void操做符可使任何一個表達式返回undefined

void 0 // 將返回undefined

在TS中,void類型表示沒有返回值,沒有返回值的函數,他的類型就是void類型

// void
let voidFunc = () => {}

 


十一,any

any:若是不指定TS的變量類型,默認爲any類型,能夠賦值爲任何類型
let x
x = 1   // 整型
x = []  // 數組
x = () => {} // 函數
不建議使用any類型,將失去使用ts的意義

十二,never

never:永遠不會有返回值的類型

1,函數拋出異常,永遠不會有返回值,類型爲never

// 函數拋出異常,永遠不會有返回值,類型爲never
let error = () => {
    throw new Error('error')
}

 

2,死循環函數永遠沒有返回值,類型爲never

// 死循環函數永遠沒有返回值,類型爲never
let endless = () => {
    while(true) {}
}
相關文章
相關標籤/搜索