超細(xì)致的TypeScript入門與實(shí)戰(zhàn)

本文是向大家介紹TypeScript基礎(chǔ)知識(shí)及用法,幫助大家快速了解,在前端項(xiàng)目中使用這門技術(shù)。TypeScript的類型推斷跟 VS Code 的良好搭配讓代碼效率有了極大提升。靜態(tài)類型檢測,會(huì)提示一些潛在的問題,使得開發(fā)者代碼更嚴(yán)謹(jǐn),低級錯(cuò)誤早發(fā)現(xiàn)早解決。同時(shí)TypeScript類型定義使得代碼的可讀性增強(qiáng),統(tǒng)一規(guī)范,可有效降低項(xiàng)目維護(hù)成本。

1.TypeScript簡介

什么是TypeScript?

TypeScript是微軟開發(fā)的一個(gè)開源的編程語言,通過在JavaScript的基礎(chǔ)上添加靜態(tài)類型定義構(gòu)建而成。TypeScript通過TypeScript編譯器或Babel轉(zhuǎn)譯為JavaScript代碼,可運(yùn)行在任何瀏覽器,任何操作系統(tǒng)。——來自TypeScript官方

1.1 TypeScript類型系統(tǒng)

從TypeScript的名字就可以看出來,「類型」是其最核心的特性。 我們知道,JavaScript是一門非常靈活的編程語言:

它沒有類型約束,一個(gè)變量可能初始化時(shí)是字符串,過一會(huì)兒又被賦值為數(shù)字。

由于隱式類型轉(zhuǎn)換的存在,有的變量的類型很難在運(yùn)行前就確定。

基于原型的面向?qū)ο缶幊蹋沟迷蜕系膶傩曰蚍椒梢栽谶\(yùn)行時(shí)被修改。

函數(shù)可以賦值給變量,也可以當(dāng)作參數(shù)或返回值。

這種靈活性就像一把雙刃劍,一方面使得JavaScript蓬勃發(fā)展,無所不能。另一方面也使得它的代碼質(zhì)量參差不齊, 維護(hù)成本高,運(yùn)行時(shí)錯(cuò)誤多。而TypeScript的類型系統(tǒng),在很大程度上彌補(bǔ)了JavaScript的缺點(diǎn)。

1.2 TypeScript 是靜態(tài)類型

類型系統(tǒng)按照「類型檢查的時(shí)機(jī)」來分類,可以分為動(dòng)態(tài)類型和靜態(tài)類型。

動(dòng)態(tài)類型是指在運(yùn)行時(shí)才會(huì)進(jìn)行類型檢查,這種語言的類型錯(cuò)誤往往會(huì)導(dǎo)致運(yùn)行時(shí)錯(cuò)誤。JavaScript 是一門解釋型語言,沒有編譯階段,所以它是動(dòng)態(tài)類型。

靜態(tài)類型是指編譯階段就能確定每個(gè)變量的類型,這種語言的類型錯(cuò)誤往往會(huì)導(dǎo)致語法錯(cuò)誤。TypeScript 在運(yùn)行前需要先編譯為 JavaScript,而在編譯階段就會(huì)進(jìn)行類型檢查,所以 TypeScript 是靜態(tài)類型。

1.3 TypeScript 是弱類型

類型系統(tǒng)按照「是否允許隱式類型轉(zhuǎn)換」來分類,可以分為強(qiáng)類型和弱類型。

TypeScript 是完全兼容 JavaScript 的,它不會(huì)修改 JavaScript 運(yùn)行時(shí)的特性,所以它們都是弱類型。

在完整保留 JavaScript 運(yùn)行時(shí)行為的基礎(chǔ)上,通過引入靜態(tài)類型系統(tǒng)來提高代碼的可維護(hù)性,減少可能出現(xiàn)的 bug。以下這段代碼不管是在 JavaScript 中還是在 TypeScript 中都是可以正常運(yùn)行的:

console.log(1 + '1');? // 打印出字符串 '11'

1.4 適用于任何規(guī)模

TypeScript 非常適用于大型項(xiàng)目——這是顯而易見的,類型系統(tǒng)可以為大型項(xiàng)目帶來更高的可維護(hù)性,以及更少的 bug。

在中小型項(xiàng)目中推行 TypeScript 的最大障礙就是認(rèn)為使用 TypeScript 需要寫額外的代碼,降低開發(fā)效率。但事實(shí)上,由于有[類型推論][],大部分類型都不需要手動(dòng)聲明了。相反,TypeScript 增強(qiáng)了編輯器(IDE)的功能,包括代碼補(bǔ)全、接口提示、跳轉(zhuǎn)到定義、代碼重構(gòu)等,這在很大程度上提高了開發(fā)效率。而且 TypeScript 有近百個(gè)[編譯選項(xiàng)][],如果你認(rèn)為類型檢查過于嚴(yán)格,那么可以通過修改編譯選項(xiàng)來降低類型檢查的標(biāo)準(zhǔn)。

TypeScript 還可以和 JavaScript 共存。這意味著如果你有一個(gè)使用 JavaScript 開發(fā)的舊項(xiàng)目,又想使用 TypeScript 的特性,那么你不需要急著把整個(gè)項(xiàng)目都遷移到 TypeScript,你可以使用 TypeScript 編寫新文件,然后在后續(xù)更迭中逐步遷移舊文件。如果一些 JavaScript 文件的遷移成本太高,TypeScript 也提供了一個(gè)方案,可以讓你在不修改 JavaScript 文件的前提下,編寫一個(gè)[類型聲明文件][],實(shí)現(xiàn)舊項(xiàng)目的漸進(jìn)式遷移。

1.5 安裝TypeScript

TypeScript 的命令行工具安裝方法如下:

npm install -g typescript

編譯文件:

tsc hello.ts

TypeScript 最大的優(yōu)勢之一便是增強(qiáng)了編輯器和 IDE 的功能,包括代碼補(bǔ)全、接口提示、跳轉(zhuǎn)到定義、重構(gòu)等。主流的編輯器都支持 TypeScript,就連VS Code也是基于TypeScript開發(fā)的。所以VS Code對TypeScript的支持也是非常好的,強(qiáng)烈推薦大家使用起來。


2.TypeScript類型

2.1 基本類型

2.1.1 原始數(shù)據(jù)類型

原始數(shù)據(jù)類型包括布爾值boolean、數(shù)值number、字符串string、undefined、null、void。

還有ES6 中的新類型 Symbol 和 ES10 中的新類型 BigInt。(最后兩種目前運(yùn)用的比較少,暫不做介紹)

JavaScript中沒有空值(Void)的概念,在TypeScript中,可以用void表示沒有任何返回值的函數(shù)。

undefined、null、void三種的區(qū)別是,undefined和null是所有類型的子類型。也就是說undefined和null類型的變量,可以復(fù)制給所有類型的變量。而void類型的變量不能賦值給其他類型的變量。

// 1-布爾值

let isDone: boolean = false;

// 2-數(shù)值

let dogAge: number = 3;

// 3-字符串

let dogName: string = 'Strawberry';

// 4-空值

function alertName(): void {

? alert(`My dog's name is ${dogName}`);

}

// 5-undefined、null、void三種的區(qū)別

let a1: undefined = undefined;

let a2: null = null;

let a3: void;

let b1: number = undefined // ts校驗(yàn)通過

let b2: number = a2 // ts校驗(yàn)通過

let b3: number = a3 // ts報(bào)錯(cuò):不能將類型“void”分配給類型“number”。


2.1.2 any類型和unknown類型

any 和 unknown 在 TypeScript 中是所謂的“頂級類型”。

top type [...]是 通用(universal) 類型,有時(shí)也稱為 通用超類型,因?yàn)樵谌魏谓o定類型系統(tǒng)中,所有其他類型都是子類型[...]。通常,類型是包含了其相關(guān)類型系統(tǒng)中所有可能的[值]的類型。----引用自 Wikipedia:

如果一個(gè)值的類型為 any,那么我們就可以用它做任何事。任何類型的值都可以賦值給 any 類型。類型 any 也可被可賦值給每一種類型。

unknown 類型是 any 的類型安全版本。每當(dāng)你想使用 any 時(shí),應(yīng)該先試著用 unknown。在 any 允許我們做任何事的地方,unknown 的限制則大得多。在對 unknown 類型的值執(zhí)行任何操作之前,必須先通過【類型斷言】、【相等判斷】、【類型防護(hù)】、【斷言函數(shù)】進(jìn)行限定其類型,否則會(huì)ts異常(后續(xù)章節(jié)會(huì)提到)。

使用 any,我們將會(huì)失去通常由 TypeScript 的靜態(tài)類型系統(tǒng)所給予的所有保護(hù)。因此,如果我們無法使用更具體的類型或 unknown,則只能將其用作最后的手段。

// demo-1 原始類型都可以賦值給any類型的變量

let age: number = 18;

let any_word: any = 'hello';

// demo-2 在任意值上訪問任何屬性都是允許的

let anyThing: any = 'Tom';

console.log(anyThing.myName);

console.log(anyThing.myName.firstName);

// demo-3 變量如果在聲明的時(shí)候,未指定其類型,那么它會(huì)被識(shí)別為任意值類型

let something;

something = 'seven';

something = 7;

something.setName('Tom');

// demo-4 any和unknown區(qū)別

let d1: any = 0

d1.money = 100 // ts校驗(yàn)通過

let d2: unknown = 0

d2.money = 100 // ts報(bào)錯(cuò):unknown類型不存在money屬性。


2.1.3 類型推論

TypeScript 會(huì)在沒有明確的指定類型的時(shí)候推測出一個(gè)類型,這就是類型推論。

如果定義的時(shí)候沒有賦值,不管之后有沒有賦值,都會(huì)被推斷成 any 類型而完全不被類型檢查:

// demo-1 myFavoriteNumber3類型?

let myFavoriteNumber3: any = 'seven'; // 直接定義any類型

myFavoriteNumber3 = 7;

// demo-2 myFavoriteNumber4類型?

let myFavoriteNumber4; // ts推測為any類型

myFavoriteNumber4 = 'seven';

myFavoriteNumber4 = 7;


2.1.4 聯(lián)合類型

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

let myFavoriteNumber5: string | number;

myFavoriteNumber5 = 'seven';

console.log(myFavoriteNumber5.length); // 5

myFavoriteNumber5 = 7;

console.log(myFavoriteNumber5.length); // ts報(bào)錯(cuò):number類型不存在length屬性


2.1.5 對象類型

聲明對象類型,經(jīng)常使用類型別名type和接口interface,二者在使用上的區(qū)別:

在類class的類型定義中我們推薦使用接口interface,因?yàn)榻涌趇nterface可以被一個(gè)類class實(shí)現(xiàn)(implements),但是類型別名type不但不能被extends和implements,就連自己也不能extends和implements其它類型。

在定義簡單類型、聯(lián)合類型、交叉類型、元組時(shí)我們用類型別名type來做,并且它和typeof能夠天然的結(jié)合在一起使用。

// 方式1-接口定義

interface Person {

? name: string;

? age: number;

}

// 方式2-類型別名定義

type Person = {

? name: string;

? age: number;

}

let tom: Person = {

? name: 'Tom',

? age: 25

};


2.1.6 數(shù)組類型

常用聲明方式:

【類型+方括號】表示方法 string[]

數(shù)組泛型 Array<T>

// demo-1 ts只允許數(shù)組中包括一種數(shù)據(jù)類型的值

let arr1: number[] = [1, 2, 3]

let arr2: Array<number> = [1, 2, 3]

// demo-2 如果想為數(shù)組添加不同類型的值,需要使用聯(lián)合類型

let arr3: Array<number | string> = ['aa', 2, 3] // 數(shù)組可以同時(shí)包括數(shù)值和字符串

let arr4: number[] | string[] = [1, 2, 3] // 數(shù)組只能全是數(shù)值組成,或者全字符串組成

arr4 = ['aa', 'bb']

arr4 = ['aa', 2, 3] // ts報(bào)錯(cuò):賦值類型與定義不一


2.1.7 函數(shù)類型

根據(jù)JavaScript中定義函數(shù)的2種方式:函數(shù)聲明(Function Declaration)和函數(shù)表達(dá)式(Function Expression),函數(shù)類型寫法如下:

// 1. 函數(shù)聲明(Function Declaration)

function add1(x: number, y: number): number {

? return x + y

}

add1(1, 2);

// 2. 函數(shù)表達(dá)式(Function Expression)

let add2 = (x: number, y: number): number => {

? return x + y

}

add2(1, 2);

// 可選參數(shù)必須接在必需參數(shù)后面

function add3(x: number, y?: number): void {

? console.log(x, y)

}

add3(3)


2.1.8 類型斷言

主要用于當(dāng) TypeScript 推斷出來類型并不滿足當(dāng)前需求時(shí),TypeScript 允許開發(fā)者覆蓋它的推斷,可以用來手動(dòng)指定一個(gè)值的類型。類型斷言是一個(gè)編譯時(shí)語法,不涉及運(yùn)行時(shí)。

類型斷言的常見用途有以下幾種:

聯(lián)合類型可以被斷言為其中一個(gè)類型

父類可以被斷言為子類

任何類型都可以被斷言為 any

any 可以被斷言為任何類型

要使得 A 能夠被斷言為 B,只需要 A 兼容 B 或 B 兼容 A 即可

聯(lián)合類型可以被斷言為其中一個(gè)類型,類型斷言只能夠欺騙 TS 編譯器,無法避免運(yùn)行時(shí)的錯(cuò)誤,反而濫用類型斷言可能會(huì)導(dǎo)致運(yùn)行時(shí)錯(cuò)誤。

interface Cat {

? name: string;

? run(): void;

}

interface Fish {

? name: string;

? swim(): void;

}

function swim(animal: Cat | Fish) {

? (animal as Fish).swim(); // 類型斷言,ts校驗(yàn)通過

}

const tom: Cat = {

? name: 'Tom',

? run() { console.log('run') }

};

swim(tom);

// 編譯時(shí)不會(huì)報(bào)錯(cuò),但在運(yùn)行時(shí)會(huì)報(bào)錯(cuò) Uncaught TypeError: animal.swim is not a function`

類型斷言不是類型轉(zhuǎn)換,它不會(huì)真的影響到變量的類型。

// 類型斷言

function toBoolean1(something: any): boolean {

? return something as boolean;

}

toBoolean1(1); // 返回值為 1

// 類型轉(zhuǎn)換

function toBoolean2(something: any): boolean {

? return Boolean(something);

}

toBoolean2(1); // 返回值為 true


2.1.9 聲明文件

當(dāng)使用第三方庫時(shí),我們需要引用它的聲明文件,才能獲得對應(yīng)的代碼補(bǔ)全、接口提示等功能。

聲明文件必需以 .d.ts 為后綴,聲明文件示例:

// src/jQuery.d.ts

declare var jQuery: (selector: string) => any;

推薦使用 @types 統(tǒng)一管理第三方庫的聲明文件。@types 的使用方式很簡單,直接用 npm 安裝對應(yīng)的聲明模塊即可,以 jQuery 舉例: npm install @types/jquery --save-dev

可以通過以下鏈接搜索需要的聲明文件。

https://www.typescriptlang.org/dt/search?search=

如果第三方庫沒有提供聲明文件,我們就需要自己書寫聲明文件。如何書寫聲明文件?此處略過,感興趣的話可以后期嘗試。


2.1.10 內(nèi)置對象

1.ECMAScript 標(biāo)準(zhǔn)提供的內(nèi)置對象有:

Boolean、Error、Date、RegExp 等。

更多的內(nèi)置對象,可以查看 MDN 的文檔

2.DOM 和 BOM 提供的內(nèi)置對象有:

Document、HTMLElement、Event、NodeList 等。

而他們的定義文件,則在 TypeScript 核心庫的定義文件中。

3.TypeScript 核心庫的定義文件中定義了所有瀏覽器環(huán)境需要用到的類型,并且是預(yù)置在 TypeScript 中的。

注意,TypeScript 核心庫的定義中不包含 Node.js 部分。

4.用 TypeScript 寫 Node.js

Node.js 不是內(nèi)置對象的一部分,如果想用 TypeScript 寫 Node.js,則需要引入第三方聲明文件:

npm install @types/node --save-dev


2.2 高級類型

2.2.1 Type類型別名

類型別名就是給類型起一個(gè)新名字。用法類似于接口interface,類型別名常用于原始類型、聯(lián)合類型,元祖類型等其他必須手動(dòng)編寫的類型,示例:

interface Cat {

? name: string;

? run(): void;

}

interface Fish {

? name: string;

? swim(): void;

}

type Animal = Cat | Fish;


2.2.2 字面量類型

字符串字面量類型用來約束取值只能是某幾個(gè)字符串中的一個(gè)。

// 也可以直接使用字面量進(jìn)行類型聲明

// a只能被賦值為10 不能被賦值為其他值 類似常量 很少使用

let a: 10;

a = 10;

// 字面量形式一般用于或的形式較多

// 可以使用 | 來連接多個(gè)類型(類似聯(lián)合類型)

let b: "male" | "female";

b = "male";

b = "female";


2.2.3 元祖

數(shù)組合并了相同類型的對象,而元組(Tuple)合并了不同類型的對象。

元組起源于函數(shù)編程語言(如 F#),這些語言中會(huì)頻繁使用元組。

// 定義一對值分別為 string 和 number 的元組

let Jerry: [string, number] = ['Jerry', 18];

// 當(dāng)添加越界的元素時(shí),它的類型會(huì)被限制為元組中每個(gè)類型的聯(lián)合類型

Jerry.push('male'); // ts校驗(yàn)通過

Jerry.push(true); // ts報(bào)錯(cuò):true和"string|number"類型不匹配


2.2.4 枚舉

// demo-1 簡單枚舉:枚舉成員會(huì)被賦值為從 0 開始遞增的數(shù)字,同時(shí)也會(huì)對枚舉值到枚舉名進(jìn)行反向映射

enum Days { Sun, Mon, Tue, Wed, Thu, Fri, Sat };

console.log(Days["Sun"] === 0); // true

console.log(Days["Mon"] === 1); // true

console.log(Days["Tue"] === 2); // true

console.log(Days["Sat"] === 6); // true

console.log(Days[0] === "Sun"); // true

console.log(Days[1] === "Mon"); // true

console.log(Days[2] === "Tue"); // true

console.log(Days[6] === "Sat"); // true

// demo-2 手動(dòng)賦值:未手動(dòng)賦值的枚舉項(xiàng)會(huì)接著上一個(gè)枚舉項(xiàng)遞增,需要避免覆蓋

enum DaysNew { Sun = 7, Mon = 1, Tue, Wed, Thu, Fri, Sat };

console.log(DaysNew["Sun"] === 7); // true

console.log(DaysNew["Mon"] === 1); // true

console.log(DaysNew["Tue"] === 2); // true

console.log(DaysNew["Sat"] === 6); // true


2.2.5 類

TypeScript 可以使用三種訪問修飾符(Access Modifiers),分別是 public、private 和 protected。

public 修飾的屬性或方法是公有的,可以在任何地方被訪問到,默認(rèn)所有的屬性和方法都是 public 的

private 修飾的屬性或方法是私有的,不能在聲明它的類的外部訪問

protected 修飾的屬性或方法是受保護(hù)的,它和 private 類似,區(qū)別是它在子類中也是允許被訪問的

給類加上 TypeScript 的類型很簡單,與接口類似:

class Animal {

? public name: string; // 思考1:此處改為private后運(yùn)行結(jié)果?

? public constructor(name: string) {

? ? this.name = name;

? }

? public sayHi(): string { // 思考2:此處改為private后運(yùn)行結(jié)果?

? ? return `My name is ${this.name}`;

? }

}

let a: Animal = new Animal('Jack');

console.log(a.sayHi()); // My name is Jack

「構(gòu)造函數(shù)」前加修飾符的區(qū)別:

當(dāng)構(gòu)造函數(shù)修飾為 private 時(shí),該類不允許被繼承或者實(shí)例化

當(dāng)構(gòu)造函數(shù)修飾為 protected 時(shí),該類只允許被繼承


2.2.6 類與接口

interface Alarm {

? alert(): void;

}

interface Light {

? lightOn(): void;

? lightOff(): void;

}

// demo-1 接口繼承接口

interface LightableAlarm extends Light {

? lightOn(): void;

? lightOff(): void;

}

// demo-2 類繼承接口

class Car implements Alarm, Light {

? alert() {

? ? console.log('Car alert');

? }

? lightOn() {

? ? console.log('Car light on');

? }

? lightOff() {

? ? console.log('Car light off');

? }

}

// demo-3 接口繼承類

interface LittleCar extends Car {

? console(): void;

}

let car1: LittleCar = {

? alert() {

? ? console.log('Little Car alert');

? },

? lightOn: function (): void {

? ? console.log('Little Car light on');

? },

? lightOff: function (): void {

? ? console.log('Little Car light off');

? },

? console: function (): void {

? ? console.log('Little Car');

? },

}


2.2.7 泛型

泛型(Generics)是指在定義函數(shù)、接口或類的時(shí)候,不預(yù)先指定具體的類型,而在使用的時(shí)候再指定類型的一種特性。

示例:Array<any> 允許數(shù)組的每一項(xiàng)都為任意類型。但是我們預(yù)期的是,數(shù)組中每一項(xiàng)都應(yīng)該是輸入的 value 的類型。

function createArray<T>(length: number, value: T): Array<T> {

? let result: T[] = [];

? for (let i = 0; i < length; i++) {

? ? result[i] = value;

? }

? return result;

}


2.2.8 聲明合并

如果定義了兩個(gè)相同名字的函數(shù)、接口或類,那么它們會(huì)合并成一個(gè)類型。

合并的屬性的類型必須是唯一的,如果出現(xiàn)重復(fù),類型不一致會(huì)報(bào)錯(cuò)。

interface Alarm {

? price: number;

}

interface Alarm {

? weight: number;

}

// 合并后

interface Alarm {

? price: number;

? weight: number;

}

interface Alarm {

? price: string;? // ts報(bào)錯(cuò):類型不一致

? weight: number;

}


3.實(shí)戰(zhàn):案例分享

3.1 定義提示

鼠標(biāo)放上UserInfo都會(huì)有相應(yīng)的定義提示

3.2 定義跳轉(zhuǎn)

在其他頁面運(yùn)用到UserInfo定義時(shí),鼠標(biāo)放上能快速看到定義類型和注釋,點(diǎn)擊能直接跳轉(zhuǎn)定義代碼


3.3 代碼靜態(tài)檢測

根據(jù)ts定義自動(dòng)檢測代碼,發(fā)現(xiàn)錯(cuò)誤實(shí)時(shí)提示,鼠標(biāo)放上會(huì)給出詳細(xì)信息,并提供快速修復(fù)功能。

例如:截圖中username沒有用駝峰式書寫,跟原定義不一致。點(diǎn)擊即可自動(dòng)修復(fù)。

3.4 接口定義快速引入項(xiàng)目

推薦安裝yapi-to-typescript 插件,快速自動(dòng)化獲取 YApiSwagger 的接口定義,生成 TypeScript 或 JavaScript 的接口類型及其請求函數(shù)代碼。

插件安裝方法:

npm i yapi-to-typescript

生成定義代碼命令:

npx ytt

導(dǎo)出模塊接口定義步驟:

1.categories中id獲取方式:打開yapi項(xiàng)目 --> 點(diǎn)開分類 --> 復(fù)制瀏覽器地址欄 /api/cat_ 后面的數(shù)字。

2.yapi上查看項(xiàng)目token方法:

3.ytt.config.ts配置文件參考:

import { defineConfig } from 'yapi-to-typescript';

/* yapi獲取ts定義 */

export default defineConfig([

? {

? ? serverUrl: 'http://XX.XX.XX.XX:XX', // yapi項(xiàng)目地址

? ? typesOnly: true, // 只生產(chǎn)ts定義

? ? target: 'typescript',

? ? reactHooks: {

? ? ? enabled: false,

? ? },

? ? prodEnvName: 'production',

? ? outputFilePath: 'api/index.ts', // 定義輸出目錄

? ? requestFunctionFilePath: 'api/request.ts',

? ? dataKey: 'data',

? ? projects: [

? ? ? {

? ? ? ? // yapi項(xiàng)目token,存在有效期限制

? ? ? ? token: 'XXXXXXXXXXXXxx',

? ? ? ? categories: [

? ? ? ? ? {

? ? ? ? ? ? id: 123, // 獲取方式:打開項(xiàng)目 --> 點(diǎn)開分類 --> 復(fù)制瀏覽器地址欄 /api/cat_123后面的數(shù)字

? ? ? ? ? ? getRequestFunctionName(interfaceInfo, changeCase) {

? ? ? ? ? ? ? return changeCase.camelCase(interfaceInfo.parsedPath.name);

? ? ? ? ? ? },

? ? ? ? ? },

? ? ? ? ],

? ? ? },

? ? ],

? },

]);

4.自動(dòng)生成定義截圖:

4.參考文獻(xiàn)

官方手冊:https://www.typescriptlang.org/docs/handbook/basic-types.html

入門教程:http://ts.xcatliu.com/introduction/what-is-typescript.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,431評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,637評論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,555評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,900評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,629評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,976評論 1 328
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,976評論 3 448
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,139評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,686評論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,411評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,641評論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,129評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,820評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,233評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,567評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,362評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,604評論 2 380

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