TypeScrip入門(mén)之基礎(chǔ)篇

那么我們開(kāi)始吧荷荤,

我們從基礎(chǔ)語(yǔ)言類(lèi)型開(kāi)始

JavaScript 的類(lèi)型分為兩種:原始數(shù)據(jù)類(lèi)型(Primitive data types)和對(duì)象類(lèi)型(Object types)

原始數(shù)據(jù)類(lèi)型包括:布爾值、數(shù)值采缚、字符串鹰椒、null宝鼓、undefined以及 ES6 中的新類(lèi)型 Symbol轩性。

本節(jié)主要介紹前五種原始數(shù)據(jù)類(lèi)型在 TypeScript 中的應(yīng)用。

原始數(shù)據(jù)類(lèi)型

布爾值

TypeScript是用:來(lái)進(jìn)行類(lèi)型申請(qǐng)的格遭。

let isDone: boolean = false;
// 編譯通過(guò)
// 后面約定哈街,未強(qiáng)調(diào)編譯錯(cuò)誤的代碼片段,默認(rèn)為編譯通過(guò)

注意如庭,使用構(gòu)造函數(shù) Boolean 創(chuàng)造的對(duì)象不是布爾值:

let createdByNewBoolean: boolean = new Boolean(1);

// index.ts(1,5): error TS2322: Type 'Boolean' is not assignable to type 'boolean'.
// 后面約定叹卷,注釋中標(biāo)出了編譯報(bào)錯(cuò)的代碼片段,表示編譯未通過(guò)

事實(shí)上 new Boolean() 返回的是一個(gè)Boolean對(duì)象:

let createdByNewBoolean: Boolean = new Boolean(1);

直接調(diào)用 Boolean也可以返回一個(gè) boolean 類(lèi)型:

let createdByBoolean: boolean = Boolean(1);

在 TypeScript 中坪它,boolean 是 JavaScript 中的基本類(lèi)型骤竹,而 Boolean 是 JavaScript 中的構(gòu)造函數(shù)。其他基本類(lèi)型(除了 null 和 undefined)一樣往毡,不再贅述蒙揣。

下面的類(lèi)型類(lèi)似:

數(shù)值

let age: number = 23;

字符串

let myName:string = 'Tom';

編譯結(jié)果為;

var isDone = false;
var age = 23;
var myName = 'Tom';

空值

JavaScript 沒(méi)有空值(Void)的概念开瞭,在 TypeScript 中懒震,可以用 void 表示沒(méi)有任何返回值的函數(shù):

function alertName(): void {
    alert("my name is Tom")
};

聲明一個(gè) void 類(lèi)型的變量沒(méi)有什么用罩息,因?yàn)槟阒荒軐⑺x值為 undefinednull

let unusable: void = undefined;

Null和Undefined

這兩個(gè)原始數(shù)據(jù)類(lèi)型比較有意思,他們的類(lèi)型變量只能賦值為他們本身个扰,undefinedundefined,null只能為null.

let u: undefined = undefined;
let n: null = null;

不過(guò)瓷炮,它和void的區(qū)別是,他們兩個(gè)是所有類(lèi)型的子類(lèi)型递宅。也就是說(shuō)undefinednull類(lèi)型的變量娘香,可以賦值給number類(lèi)型變量:

// 這樣不會(huì)報(bào)錯(cuò)
let num: number = undefined;
// 這樣也不會(huì)報(bào)錯(cuò)
let u: undefined;
let num: number = u;

void 類(lèi)型的變量不能賦值給 number 類(lèi)型的變量:

任意值

任意值(Any)用來(lái)表示允許賦值為任意類(lèi)型

那么什么是任意值類(lèi)型呢?

如果是一個(gè)普通類(lèi)型办龄,在賦值過(guò)程中改變類(lèi)型是不被允許的:

let myFavoriteNumber: string = 'seven';
myFavoriteNumber = 7;

編譯報(bào)錯(cuò):

hello.ts:25:1 - error TS2322: Type '7' is not assignable to type 'string'.

25 myFavoriteNumber = 7;
   ~~~~~~~~~~~~~~~~

但是any類(lèi)型可以烘绽,允許被賦值為任意類(lèi)型。

let myFavoriteNumber: any = 'seven';
myFavoriteNumber = 7;

任意值的屬性和方法

在任意值上訪問(wèn)任何屬性都是允許的:

let anyThing: any = 'hello';
console.log(anyThing.myName);
console.log(anyThing.myName.firstName);

也允許調(diào)用任何方法:

let anyThing: any = 'Tom';
anyThing.setName('Jerry');
anyThing.setName('Jerry').sayHello();
anyThing.myName.setFirstName('Cat');

可以這樣認(rèn)為俐填,聲明一個(gè)變量為任意值后安接,對(duì)它的任何操作,返回的內(nèi)容的類(lèi)型都是任意值英融。

未聲明類(lèi)型的變量

如果變量在聲明的時(shí)候沒(méi)有指定類(lèi)型盏檐,那么它的默認(rèn)類(lèi)型為任意值類(lèi)型:

let something;
something = 'seven';
something = 7;
something.setName('Tom');

相當(dāng)于

let something: any;
something = 'seven';
something = 7;
something.setName('Tom');

類(lèi)型推論

如果沒(méi)有明確的指定類(lèi)型,那么TypeScript會(huì)依照類(lèi)型推論Type Inference 的規(guī)則推斷出一個(gè)類(lèi)型矢赁。

什么是類(lèi)型推論呢糯笙?

例如:

let myFavoriteNumber = 'seven';
myFavoriteNumber = 7;

// index.ts(2,1): error TS2322: Type 'number' is not assignable to type 'string'.

它就相當(dāng)于:


let myFavoriteNumber: string = 'seven';
myFavoriteNumber = 7;
// index.ts(2,1): error TS2322: Type 'number' is not assignable to type 'string'.

報(bào)的錯(cuò)誤都一樣贬丛,就是說(shuō)撩银,在你聲明變量的時(shí)候,如果你沒(méi)有設(shè)置類(lèi)型豺憔,但是你給它指定了具體的值额获,那么它就會(huì)推斷它的類(lèi)型為你制定值的類(lèi)型。

同理恭应,如果你在聲明變量的時(shí)候沒(méi)有指定值抄邀,那么它就推斷它的類(lèi)型為any任意值類(lèi)型。

let myFavoriteNumber;
myFavoriteNumber = 'seven';
myFavoriteNumber = 7;

聯(lián)合類(lèi)型

聯(lián)合類(lèi)型(Union Types)表示取值可以為多種類(lèi)型中的一種昼榛。

let myFavoriteNumber: string | number = 'seven';
myFavoriteNumber = 7;

同樣是上面的代碼境肾,你設(shè)置了字符串和數(shù)字,那么它就可以設(shè)置這兩種胆屿。

let myFavoriteNumber: string | number ;
myFavoriteNumber = false;
// index.ts(2,1): error TS2322: Type 'boolean' is not assignable to type 'string | number'.
//   Type 'boolean' is not assignable to type 'number'.

聯(lián)合類(lèi)型是用豎線 |來(lái)分割每個(gè)類(lèi)型奥喻。

這里的含義是,你可以是字符串或者數(shù)字非迹,但是不可以是其他的類(lèi)型环鲤。

訪問(wèn)聯(lián)合類(lèi)型的屬性或方法

當(dāng)TypeScript不確定一個(gè)聯(lián)合類(lèi)型的變量到底是哪個(gè)類(lèi)型的時(shí)候,我們只能訪問(wèn)此聯(lián)合類(lèi)型的所有類(lèi)型里共有的屬性或方法:

function getLength(something: string | number): number {
    return something.length;
}

hello.ts:39:22 - error TS2339: Property 'length' does not exist on type 'string 

上例中憎兽,length不是stringnumber的共有屬性冷离,所以會(huì)報(bào)錯(cuò)吵冒。

訪問(wèn)stringnumber的共有屬性是沒(méi)有問(wèn)題的:

function getString(something: string | number): string {
    return something.toString();
}

聯(lián)合類(lèi)型的變量在賦值的時(shí)候,會(huì)根據(jù)類(lèi)型推論的規(guī)則推斷出一個(gè)類(lèi)型:

let myFavoriteNumber: string|number;
myFavoriteNumber = 'seven';
console.log(myFavoriteNumber.length);

myFavoriteNumber = 7;
console.log(myFavoriteNumber.lenght);
// index.ts(5,30): error TS2339: Property 'length' does not exist on type 'number'.

上面的第二行西剥,類(lèi)型推斷字符串痹栖,所以length不報(bào)錯(cuò),
而第四行瞭空,類(lèi)型推斷為數(shù)字结耀,所以length為不報(bào)錯(cuò)。

對(duì)象的類(lèi)型——接口

這個(gè)在java語(yǔ)言中非常重要的概念匙铡,有一個(gè)說(shuō)法是面向接口編程图甜。在TypeScript中,我們使用接口interface來(lái)定義對(duì)象的類(lèi)型鳖眼。

什么是接口

在面向?qū)ο笳Z(yǔ)言中黑毅,它是對(duì)行為的抽象,而具體如何行動(dòng)需要由類(lèi)classes去實(shí)現(xiàn)implements.

TypeScript中的接口是一個(gè)非常靈活的概念钦讳,除了可用于一部分行為進(jìn)行抽象外矿瘦,也常用于對(duì)象的形狀Shape進(jìn)行概括。

例如:

interface Person {
    name:string;
    age:number;
}

let tom:Person = {
    name:"Tom",
    age:23
};

這個(gè)有點(diǎn)想抽象類(lèi)愿卒,我們看到上面代碼中缚去,我們創(chuàng)建了一個(gè)對(duì)象tom,然后把它的類(lèi)型設(shè)置為接口Person琼开。這樣的話易结,我們就約束了tom的形狀必須和接口Person一直。接口一般首字母大寫(xiě)柜候。有的編程語(yǔ)言中會(huì)建議接口的名稱(chēng)加上I為前綴搞动。

因?yàn)槟阍O(shè)定了對(duì)象的類(lèi)型是接口Person,所以必須完全一致渣刷,少一些屬性和多一些屬性鹦肿,通通不允許:

interface Person {
    name:string;
    age:number;
}

let tom:Person = {
    name:"Tom",
};

//hello.ts:59:5 - error TS2322: Type '{ name: string; }' is //not assignable to type 'Person'.
//  Property 'age' is missing in type '{ name: string; }'.

interface Person {
    name:string;
    age:number;
}

let tom:Person = {
    name:"Tom",
    age:23,
    gender:'male'
};

//hello.ts:62:5 - error TS2322: Type '{ name: string; age: //number; gender: string; }' is not assignable to type //'Person'.
//  Object literal may only specify known properties, and //'gender' does not exist in type 'Person'.

所以,賦值的時(shí)候辅柴,變量的形狀必須和接口的形狀保持一致箩溃。

可是我不想保持一致怎么辦呢?可選屬性出場(chǎng)

可選屬性

可選屬性是通過(guò)變量后面加一個(gè)?問(wèn)號(hào)來(lái)實(shí)現(xiàn)的碌嘀,它的意思是你可以選擇這個(gè)屬性不存在涣旨。但是不可以添加未定義的屬性。

interface Person {
    name:string;
    age?:number;
}

let tom:Person = {
    name:"Tom",
};

可選屬性筏餐,你可以存在或者不存在

interface Person {
    name:string;
    age?:number;
}

let tom:Person = {
    name:"Tom",
    age:23,
    gender:'male'
};

//hello.ts:62:5 - error TS2322: Type '{ name: string; age: //number; gender: string; }' is not assignable to type //'Person'.
//  Object literal may only specify known properties, and //'gender' does not exist in type 'Person'.

不可以添加不存在的屬性开泽。

對(duì)象的類(lèi)型 接口的意義就是為了約束對(duì)象的創(chuàng)建。

任意類(lèi)型

有時(shí)候我們希望一個(gè)借口允許有任意的屬性魁瞪,可以使用下面的方式:


interface Person {
    name:string;
    age?:number;
    [propName: string]:any;
}

let tom:Person = {
    name:"Tom",
    age:23,
    gender:'male'
};

我們通過(guò)[propName: string]定義了任意屬性取string的值穆律,而我們需要注意的是惠呼,一旦定義了任意屬性,那么確定屬性和可選屬性都必須是它的子屬性峦耘。


interface Person {
    name:string;
    age?:number;
    [propName: string]:string;
}

let tom:Person = {
    name:"Tom",
    age:23,
    gender:'male'
};

我們把上面的any改為string,那么不確定屬性agenumber剔蹋,不屬于string,就報(bào)錯(cuò)了辅髓。
編譯的結(jié)果:

hello.ts:56:5 - error TS2411: Property 'age' of type 'number' is not assignable to string index type 'string'.

56     age?:number;
       ~~~

hello.ts:60:5 - error TS2322: Type '{ name: string; age: number; gender: string; }' is not assignable to type 'Person'.
Property 'age' is incompatible with index signature.
Type 'number' is not assignable to type 'string'.

60 let tom:Person = {

只讀屬性

我們還可以設(shè)置只讀類(lèi)型泣崩,只有在創(chuàng)建的時(shí)候賦值,其他的時(shí)候不可以賦值洛口,那么就可以使用readonly定義只讀屬性了矫付。

interface Person {
    readonly id:number;
    name:string;
    age?:number;
    [propName: string]:any;
}

let tom:Person = {
    id:12345,
    name:"Tom",
    age:23,
    gender:'male'
};

tom.id = 2222;

//hello.ts:68:5 - error TS2540: Cannot assign to 'id' because //it is a constant or a read-only property.

//68 tom.id = 2222;

類(lèi)似于上面的代碼,我們把readonly放在屬性名稱(chēng)的前面,在上面的tom對(duì)象中第焰,我們創(chuàng)建的時(shí)候就已經(jīng)直接賦值了买优,所以在后面再次賦值的時(shí)候,就報(bào)錯(cuò)挺举。

注意:只讀的約束存在于第一次給對(duì)象賦值的時(shí)候杀赢,而不是第一次給只讀屬性賦值的時(shí)候。

interface Person {
    readonly id:number;
    name:string;
    age?:number;
    [propName: string]:any;
}

let tom:Person = {
    
    name:"Tom",
    age:23,
    gender:'male'
};

tom.id = 2222;

hello.ts:61:5 - error TS2322: Type '{ name: string; age: number; gender: string; }' is not assignable to type 'Person'.
  Property 'id' is missing in type '{ name: string; age: number; gender: string; }'.

61 let tom:Person = {
       ~~~

hello.ts:68:5 - error TS2540: Cannot assign to 'id' because it is a constant or a read-only property.

68 tom.id = 2222;

上面報(bào)錯(cuò)有兩次湘纵,一是在創(chuàng)建對(duì)象的時(shí)候脂崔,沒(méi)有給只讀屬性id賦值,二是它是只讀屬性梧喷,不可以在此賦值砌左。

關(guān)于接口行為的約束,我們?cè)诤竺鏁?huì)有詳細(xì)的章節(jié)伤柄。

數(shù)組的類(lèi)型

TypeScript中绊困,數(shù)組類(lèi)型有多重定義方式文搂,比較靈活适刀。

「類(lèi)型 + 方括號(hào)」表示法

java的類(lèi)似

let array:number[] = [1,2,3,4,5,6];
let sty_arr:string[] = ['1','2'];

數(shù)組中不可以出現(xiàn)其他的數(shù)據(jù)類(lèi)型:

let array:number[] = [1,2,3,4,5,6,"1"];

hello.ts:70:35 - error TS2322: Type 'string' is not assignable to type 'number'.

70 let array:number[] = [1,2,3,4,5,6,"1"];

我們?cè)囈幌率欠窨梢月暶髀?lián)合類(lèi)型的數(shù)組,既包含字符串又包含數(shù)字

let com_arr: string | number [] = ["1",1];

hello.ts:73:5 - error TS2322: Type '(string | number)[]' is not assignable to type 'string | number[]'.
  Type '(string | number)[]' is not assignable to type 'number[]'.
    Type 'string | number' is not assignable to type 'number'.
      Type 'string' is not assignable to type 'number'.

73 let com_arr: string | number [] = ["1",1];

看上面錯(cuò)誤煤蹭,這樣聲明的數(shù)組是不行的笔喉。需要改成下面這樣。

let com_arr: (string | number) [] = ["1",1];

果然可以硝皂。666常挚,不過(guò)我們還是不要這樣用了,你用TypeScript就是為了約束稽物,你這樣玩還不如直接寫(xiě):

let com_arr = ["1", 1];

數(shù)組的泛型

我們也可以用數(shù)組的泛型來(lái)展示數(shù)組奄毡。Array<elemType>

let array: Array<number> = [1,2,3,4,5];
let array1: Array<string> = ["1","2"];
let array3: Array<string|number> = ["1","2",1];
let array4:Array<any> = [1,"2",{"a":1}];

同樣我們可以用any來(lái)定義數(shù)組。

關(guān)于泛型贝或,可以參考泛型一章.

用接口表示數(shù)組

interface NumberArray {
    [index:number]:number;
}

// let array:NumberArray = [1,2,3,4];
let array :NumberArray = ["a"];

hello.ts:86:27 - error TS2322: Type 'string' is not assignable to type 'number'.

86 let array :NumberArray = ["a"];

  hello.ts:82:5
    82     [index:number]:number;
           ~~~~~~~~~~~~~~~~~~~~~~
    The expected type comes from this index signature.

NumberArray表示:只要index的類(lèi)型是number,那么值必須是number

如果我們?cè)O(shè)置的數(shù)組是字符串的話吼过,那么它會(huì)報(bào)錯(cuò)锐秦。

類(lèi)數(shù)組

類(lèi)數(shù)組不是數(shù)組類(lèi)型,比如內(nèi)置對(duì)象arguments:

function sum() {
    let args:number [] = arguments;
}

hello.ts:89:9 - error TS2322: Type 'IArguments' is not assignable to type 'number[]'.
  Property 'pop' is missing in type 'IArguments'.

89     let args:number [] = arguments;

我們可以看到上面的錯(cuò)誤說(shuō)的是IArguments類(lèi)型無(wú)法匹配為nujber []類(lèi)型盗忱。所以我們可以這樣寫(xiě):

function sum() {
    let args:IArguments = arguments;
}

沒(méi)有報(bào)錯(cuò)酱床,妥妥的。

函數(shù)的類(lèi)型

大家要記得趟佃,函數(shù)是JavaScript的一等公民

函數(shù)聲明

JavaScript中扇谣,有兩種常見(jiàn)的定義函數(shù)的方式--函數(shù)聲明和函數(shù)表達(dá)式:

//函數(shù)聲明 (Function Declaration)
function sum(x,y){
    return x+y;
}

//函數(shù)表達(dá)式 (Function Expression)
let mySum = function(x,y){
    return x + y;
}

一個(gè)函數(shù)有輸入和輸出,要在 TypeScript 中對(duì)其進(jìn)行約束闲昭,需要把輸入和輸出都考慮到罐寨,其中函數(shù)聲明的類(lèi)型定義較簡(jiǎn)單:

function sum(x:number,y:number):number {
    return x + y;
}

注意:輸入多余的或者少輸入都會(huì)報(bào)錯(cuò)。我就不在這里試了序矩。

函數(shù)表達(dá)式

感覺(jué)這里是個(gè)坑衩茸。

聲明一個(gè)函數(shù)表達(dá)式,會(huì)寫(xiě)成這樣:

let mySum = function (x: number, y: number):number {
    return x + y;
}

沒(méi)有報(bào)錯(cuò)贮泞,可以編譯楞慈,實(shí)際上上面的代碼只對(duì)燈油右側(cè)的匿名函數(shù)進(jìn)行了類(lèi)型定義,而等號(hào)左邊的mySum啃擦,是對(duì)賦值操作進(jìn)行類(lèi)型推論出來(lái)的囊蓝。如果我們需要手動(dòng)為它添加類(lèi)型,則應(yīng)該寫(xiě)成這樣令蛉。

let mySum:(x:number,y:number)=>number = function (x: number, y: number):number {
    return x + y;
}

這里不要把TypeScript=>ES6=>混淆了聚霜。

怎么可能不混淆嗎会油?

TypeScript的類(lèi)型定義中摄凡,=>用來(lái)表示函數(shù)的定義,左邊是輸入的參數(shù)的類(lèi)型蟋软,右邊是返回的類(lèi)型祷安。

ES6中姥芥,=>表示箭頭函數(shù)。不在介紹汇鞭。

用接口定義函數(shù)的形狀

那么我們現(xiàn)在用接口來(lái)定義個(gè)函數(shù)所需要的形狀:

interface SearchFunc {
    (source:string,subString:string):boolean;
}

let mySearch:SearchFunc = function (source:string,subString:string) {
    return source.search(subString) !== -1; 
}

我們用接口定義了函數(shù)的形狀凉唐,左邊是輸入的類(lèi)型,右邊是輸出的類(lèi)型霍骄。

可選參數(shù)

前面我們說(shuō)道輸入多余或者少輸入都會(huì)報(bào)錯(cuò)台囱,那么如何定義和選擇的參數(shù)呢?與接口中的可選屬性類(lèi)型读整,我們用?表示可選的參數(shù):

function buildName(firstName: string, lastName?: string) {
    if (lastName) {
        return firstName + ' ' + lastName;
    } else {
        return firstName;
    }
}
let tomcat = buildName('Tom', 'Cat');
let tom = buildName('Tom');

需要注意的是簿训,可選參數(shù)必須接在必需參數(shù)后面。換句話說(shuō),可選參數(shù)后面不允許再出現(xiàn)必須參數(shù)了:

function buildName(firstName?: string, lastName: string) {
    if (firstName) {
        return firstName + ' ' + lastName;
    } else {
        return lastName;
    }
}
let tomcat = buildName('Tom', 'Cat');
let tom = buildName(undefined, 'Tom');

// index.ts(1,40): error TS1016: A required parameter cannot follow an optional parameter.

參數(shù)默認(rèn)值

TypeScript中參數(shù)的默認(rèn)值和ES6一樣的寫(xiě)法强品,TypeScript會(huì)將添加了默認(rèn)值的參數(shù)識(shí)別為可選參數(shù):

function buildName(firstName:string,lastName:string = "Cat") {
    return firstName +" " +lastName;
}

let tomcat = buildName('Tom','Cat');
let tom = buildName('Tom');

此時(shí)就不受可選參數(shù)必須接在必須參數(shù)后面的限制了:

function buildName(firstName:string,lastName:string = "Cat") {
    return firstName +" " +lastName;
}

let tomcat = buildName('Tom','Cat');
let tom = buildName(undefined,'Tom');

剩余參數(shù)

ES6 中豺总,可以使用 ...rest 的方式獲取函數(shù)中的剩余參數(shù)(rest 參數(shù)):

function push(array,...items) {
    items.forEach(function (item) {
        array.push(item);
    });
}

let a  = [];
push(a,2,3,4);

我們可以看到,實(shí)際上items是一個(gè)數(shù)組择懂,所以我們可以用數(shù)組的方式來(lái)定義它喻喳。

function push(array:any [],...items:any []) {
    items.forEach(function (item) {
        array.push(item);
    });
}

let a  = [];
push(a,2,3,4);

需要注意的是,rest參數(shù)只能是最后一個(gè)參數(shù)困曙。

重載

重載允許一個(gè)函數(shù)接受不同數(shù)量或者不同類(lèi)型的參數(shù)時(shí)表伦,做出不同的處理。

比如我們實(shí)現(xiàn)下面的函數(shù)慷丽。利用聯(lián)合類(lèi)型蹦哼,我們可以這樣實(shí)現(xiàn)。

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('');
    }
}

不過(guò)這樣有一個(gè)缺點(diǎn)要糊,就是不能夠精確的表達(dá)纲熏,輸入為數(shù)字的時(shí)候,輸出也應(yīng)該是數(shù)字锄俄,輸入字符串的時(shí)候局劲,輸出也應(yīng)該是字符串。

我們可以使用多個(gè)reverse的函數(shù)類(lèi)型:

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('');
    }
}

上例中奶赠,我們重復(fù)定義了多次函數(shù)reverse鱼填,幾次都是函數(shù)定義,最后一次是函數(shù)實(shí)現(xiàn)毅戈,在編輯的代碼提示中苹丸,可以正確的看到前兩個(gè)提示。

需要注意的是苇经,TypeScript會(huì)優(yōu)先從最前面的函數(shù)定義開(kāi)始匹配赘理,所以多個(gè)函數(shù)定義如果有包含關(guān)系,需要優(yōu)先把精確的電影以寫(xiě)在前面扇单。

類(lèi)型斷言

類(lèi)型斷言(Type Assertion) 可以用來(lái)手動(dòng)指定一個(gè)值的類(lèi)型商模。但是它并不是類(lèi)型轉(zhuǎn)換。

語(yǔ)法

<類(lèi)型>值

值 as 類(lèi)型

tsx語(yǔ)法中必須用后一種令花。

例如:將一個(gè)聯(lián)合類(lèi)型的變量指定為更加具體的的類(lèi)型阻桅。

之前提到過(guò),當(dāng) TypeScript 不確定一個(gè)聯(lián)合類(lèi)型的變量到底是哪個(gè)類(lèi)型的時(shí)候兼都,我們只能訪問(wèn)此聯(lián)合類(lèi)型的所有類(lèi)型里共有的屬性或方法:

function getLength(something:string|number):number {
    return something.length;
}
hello.ts:154:22 - error TS2339: Property 'length' does not exist on type 'string | number'.
  Property 'length' does not exist on type 'number'.

154     return something.length;

我們有時(shí)候需要在還不確定類(lèi)型的時(shí)候就訪問(wèn)其中的一個(gè)類(lèi)型的屬性或方法,比如:

function getLength(something:string|number):number {
   if(something.length){
       return something.length;
   }else{
       return something.toString.length;
   }
}
hello.ts:154:17 - error TS2339: Property 'length' does not exist on type 'string | number'.
  Property 'length' does not exist on type 'number'.

154    if(something.length){
                    ~~~~~~

hello.ts:155:25 - error TS2339: Property 'length' does not exist on type 'string | number'.
  Property 'length' does not exist on type 'number'.

155        return something.length;

可以看到上面的報(bào)錯(cuò)稽寒,這個(gè)時(shí)候我們就可以使用類(lèi)型斷言扮碧,將something斷言成string:

function getLength(something:string|number):number {
   if((<string>something).length){
       return (<string>something).length;
   }else{
       return something.toString.length;
   }
}

類(lèi)型斷言的用法如上,在需要斷言的變量前加上<Type>就可以。

類(lèi)型斷言不是類(lèi)型轉(zhuǎn)換慎王,斷言成一個(gè)聯(lián)合類(lèi)型中不存在的類(lèi)型是不允許的蚓土。

function boBoolean(something:string|number):boolean {
    return <boolean>something;
}

hello.ts:162:12 - error TS2352: Conversion of type 'string | number' to type 'boolean' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
  Type 'number' is not comparable to type 'boolean'.

162     return <boolean>something;

類(lèi)型斷言不是類(lèi)型轉(zhuǎn)換,因?yàn)槟悴荒馨阉鼜?qiáng)制轉(zhuǎn)換為不存在的類(lèi)型赖淤。

聲明文件

聲明文件官方連接

內(nèi)置對(duì)象

JavaScript 中有很多內(nèi)置對(duì)象蜀漆,它們可以直接在 TypeScript 中當(dāng)做定義好了的類(lèi)型。

內(nèi)置對(duì)象是指根據(jù)標(biāo)準(zhǔn)在全局作用域(Global)上存在的對(duì)象咱旱。這里的標(biāo)準(zhǔn)是指 ECMAScript 和其他環(huán)境(比如 DOM)的標(biāo)準(zhǔn)确丢。

ECMAScript 的內(nèi)置對(duì)象

ECMAScript標(biāo)準(zhǔn)提供的內(nèi)置對(duì)象有:
Boolean,String,Error,Date,RegExp
我們都可以在TypeScript中將變量定義為這些類(lèi)型。

let b:Boolean = new Boolean(1);
let e:Error = new Error("error occurred");
let d:Date = new Date();
let r:RegExp = /[a-z]/;
let s:String = new String("a");
let n:Number = new Number(1);

更多的內(nèi)置對(duì)象吐限,可以查看MDN的文檔
而他們的定義文件鲜侥,則在 TypeScript 核心庫(kù)的定義文件中。

DOM 和 BOM 的內(nèi)置對(duì)象

DOM和BOM提供的內(nèi)置對(duì)象:
Document诸典、HTMLElement描函、Event、NodeList等狐粱。

TypeScript中經(jīng)常用到這些類(lèi)型:

let body:HTMLElement = document.body;
let allDiv:NodeList = document.querySelectorAll('div');
document.addEventListener('click',function (e:MouseEvent) {
    //DO something
})

它們同樣定義在 TypeScript 核心庫(kù)的定義文件中舀寓。

這里是我學(xué)習(xí)的網(wǎng)址教程

大家加油。肌蜻。基公。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市宋欺,隨后出現(xiàn)的幾起案子轰豆,更是在濱河造成了極大的恐慌,老刑警劉巖齿诞,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件酸休,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡祷杈,警方通過(guò)查閱死者的電腦和手機(jī)斑司,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)但汞,“玉大人宿刮,你說(shuō)我怎么就攤上這事∷嚼伲” “怎么了僵缺?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)踩叭。 經(jīng)常有香客問(wèn)我磕潮,道長(zhǎng)翠胰,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任自脯,我火速辦了婚禮之景,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘膏潮。我一直安慰自己锻狗,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布焕参。 她就那樣靜靜地躺著轻纪,像睡著了一般。 火紅的嫁衣襯著肌膚如雪龟糕。 梳的紋絲不亂的頭發(fā)上桐磁,一...
    開(kāi)封第一講書(shū)人閱讀 49,166評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音讲岁,去河邊找鬼我擂。 笑死,一個(gè)胖子當(dāng)著我的面吹牛缓艳,可吹牛的內(nèi)容都是我干的校摩。 我是一名探鬼主播,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼阶淘,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼衙吩!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起溪窒,我...
    開(kāi)封第一講書(shū)人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤坤塞,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后澈蚌,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體摹芙,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年宛瞄,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了浮禾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡份汗,死狀恐怖盈电,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情杯活,我是刑警寧澤匆帚,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站轩猩,受9級(jí)特大地震影響卷扮,放射性物質(zhì)發(fā)生泄漏荡澎。R本人自食惡果不足惜均践,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一晤锹、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧彤委,春花似錦鞭铆、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至斯辰,卻和暖如春舶担,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背彬呻。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工衣陶, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人闸氮。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓剪况,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親蒲跨。 傳聞我的和親對(duì)象是個(gè)殘疾皇子译断,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容

  • 這是16年5月份編輯的一份比較雜亂適合自己觀看的學(xué)習(xí)記錄文檔,今天18年5月份再次想寫(xiě)文章或悲,發(fā)現(xiàn)簡(jiǎn)書(shū)還為我保存起的...
    Jenaral閱讀 2,733評(píng)論 2 9
  • 第2章 基本語(yǔ)法 2.1 概述 基本句法和變量 語(yǔ)句 JavaScript程序的執(zhí)行單位為行(line)孙咪,也就是一...
    悟名先生閱讀 4,118評(píng)論 0 13
  • 看到男神李健和嬌妻孟小蓓的生活片段,一下子陷入艷羨的情緒巡语,能在煙火人間活出仙氣翎蹈,享受二人的愜意時(shí)光,是一種怎...
    天明懶畫(huà)眉閱讀 420評(píng)論 0 2
  • 最近在讀杜子建的書(shū)捌臊,他在書(shū)中是這么說(shuō)經(jīng)歷和閱歷的杨蛋。 經(jīng)歷,是指你走過(guò)了多少路理澎、遇到過(guò)多少事逞力;閱歷,是指你觀察過(guò)多少...
    西蘭花開(kāi)8528閱讀 231評(píng)論 0 1
  • 2018―10―09 姓名:葉彩霞 【日精進(jìn)打卡第182天】2018.10.09 第367期(無(wú)錫市) 樂(lè)觀三組 ...
    透明的水泡閱讀 132評(píng)論 0 0