類(lèi)型
斷言
通過(guò)類(lèi)型斷言這種方式可以告訴編譯器,“相信我,我知道自己在干什么”。
類(lèi)型斷言好比其它語(yǔ)言里的類(lèi)型轉(zhuǎn)換,但是不進(jìn)行特殊的數(shù)據(jù)檢查和解構(gòu)。 它沒(méi)有運(yùn)行時(shí)的影響,只是在編譯階段起作用
// 方式一
let someValue: any = "this is a string";
let strLength: number = (<string>someValue).length;
// 方式二:as語(yǔ)法
let someValue: any = "this is a string";
let strLength: number = (someValue as string).length;
基本類(lèi)型
let name: string = "bob";
let decLiteral: number = 6;
數(shù)組
let list: number[] = [1, 2, 3];
let list: Array<number> = [1, 2, 3];
TypeScript具有ReadonlyArray<T>類(lèi)型,它與Array<T>相似,只是把所有可變方法去掉了,因此可以確保數(shù)組創(chuàng)建后再也不能被修改
let a: number[] = [1, 2, 3, 4];
let ro: ReadonlyArray<number> = a;
ro[0] = 12; // error!
ro.push(5); // error!
ro.length = 100; // error!
// 把整個(gè)ReadonlyArray賦值到一個(gè)普通數(shù)組也是不可以的
a = ro; // error!
// 可以用類(lèi)型斷言重寫(xiě)
a = ro as number[];
元組
元組類(lèi)型允許表示一個(gè)已知元素?cái)?shù)量和類(lèi)型的數(shù)組,各元素的類(lèi)型不必相同。
// 定義 a tuple type
let x: [string, number];
// Initialize it
x = ['hello', 10]; // OK
// Initialize it incorrectly
x = [10, 'hello']; // Error
// 使用
console.log(x[0].substr(1)); // OK
console.log(x[1].substr(1)); // Error, 'number' does not have 'substr'
枚舉
enum類(lèi)型是對(duì)JavaScript標(biāo)準(zhǔn)數(shù)據(jù)類(lèi)型的一個(gè)補(bǔ)充。 像C#等其它語(yǔ)言一樣,使用枚舉類(lèi)型可以為一組數(shù)值賦予友好的名字。(反向映射)
enum Color {Red, Green, Blue}
let c: Color = Color.Green;
默認(rèn)情況下,從0開(kāi)始為元素編號(hào)。你也可以手動(dòng)的指定成員的數(shù)值
enum Color {Red = 1, Green, Blue}
let c: Color = Color.Green;
枚舉類(lèi)型提供的一個(gè)便利是你可以由枚舉的值得到它的名字。
enum Color {Red = 1, Green, Blue}
let colorName: string = Color[2];
console.log(colorName); // 顯示'Green'因?yàn)樯厦娲a里它的值是2
Any
我們會(huì)想要為那些在編程階段還不清楚類(lèi)型的變量指定一個(gè)類(lèi)型。 這些值可能來(lái)自于動(dòng)態(tài)的內(nèi)容,比如來(lái)自用戶輸入或第三方代碼庫(kù)。 這種情況下,我們不希望類(lèi)型檢查器對(duì)這些值進(jìn)行檢查而是直接讓它們通過(guò)編譯階段的檢查。 那么我們可以使用 any類(lèi)型來(lái)標(biāo)記這些變量。
let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean
在對(duì)現(xiàn)有代碼進(jìn)行改寫(xiě)的時(shí)候,any類(lèi)型是十分有用的。
Object有相似的作用,但是 Object類(lèi)型的變量只是允許你給它賦任意值,卻不能夠在它上面調(diào)用任意的方法,即便它真的有這些方法
let notSure: any = 4;
notSure.ifItExists(); // okay, ifItExists might exist at runtime
notSure.toFixed(); // okay, toFixed exists (but the compiler doesn't check)
let prettySure: Object = 4;
prettySure.toFixed(); // Error: Property 'toFixed' doesn't exist on type 'Object'.
Void
某種程度上來(lái)說(shuō),void類(lèi)型像是與any類(lèi)型相反,它表示沒(méi)有任何類(lèi)型
function warnUser(): void {
console.log("This is my warning message");
}
接口
意義:對(duì)值的結(jié)構(gòu)進(jìn)行類(lèi)型檢查。typeScript的核心原則之一是對(duì)值所具有的結(jié)構(gòu)進(jìn)行類(lèi)型檢查。接口的作用就是為這些類(lèi)型命名和為你的代碼或第三方代碼定義契約
interface LabelledValue {
label: string;
}
function printLabel(labelledObj: LabelledValue) {
console.log(labelledObj.label);
}
let myObj = {size: 10, label: "Size 10 Object"};
printLabel(myObj);
只讀屬性
interface Point {
readonly x: number;
readonly y: number;
}
let p1: Point = { x: 10, y: 20 };
p1.x = 5; // error!
泛型?????
符號(hào)
?.
用于訪問(wèn)可能為 null 或 undefined 的屬性或方法,以避免出現(xiàn)異常錯(cuò)誤。異常會(huì)返回undefined,不會(huì)報(bào)錯(cuò)
??
提供備選項(xiàng),前面變量為null或者undefined時(shí),取后面的值
|| 與?? 的區(qū)別
1、||d的假值判斷有:false、0、空字符串、null、undefined 等
2、?? 判斷左側(cè)操作數(shù)為null或undefined時(shí),返回右側(cè)操作數(shù)
??=
x ??= 5,如果x為null或者undefined時(shí),把5賦值給x
泛型
// 定義泛型
function identity<T>(arg: T): T {
return arg;
}
// 定義泛型
function loggingIdentity<T>(arg: T[]): T[] {
console.log(arg.length); // Array has a .length, so no more error
return arg;
}
// 用法一
let output = identity<string>("myString"); // type of output will be 'string'
// 用法二:類(lèi)型推論 --普遍用法
let output = identity("myString");
我們給identity添加了類(lèi)型變量T。 T幫助我們捕獲用戶傳入的類(lèi)型(比如:number),之后我們就可以使用這個(gè)類(lèi)型。 之后我們?cè)俅问褂昧?T當(dāng)做返回值類(lèi)型。現(xiàn)在我們可以知道參數(shù)類(lèi)型與返回值類(lèi)型是相同的了
用法見(jiàn)用法二的普遍用法:注意我們沒(méi)必要使用尖括號(hào)(<>)來(lái)明確地傳入類(lèi)型;編譯器可以查看myString的值,然后把T設(shè)置為它的類(lèi)型。