今天寫的是串講。串講呢,就是把以前的知識串起來撿重點。javascript
再重複一下,Typescript 的本質是對靜態類型的處理。在實際項目開發中,編寫 Typescript 就是定義類型。css
interface UserModel {
showName(name: string[] | null): object;
}
class User implements UserModel {
name: string,
constructor(name: string){
this.name = name;
}
}
複製代碼
這是很一個很普通的類型文件的定義,關於 Typescript 定義靜態類型的歷史,簡要普及下html
這裏重點介紹下 DefinitelyTypedjava
DefinitelyTyped 的工做方式是將**類型聲明文件(xxx.d.ts
)**發佈到 npm 社區上(本地開發的編輯器上能夠檢測到)。git
說了這麼多,來一段經典的 jQuery 的類型聲明文件github
// types/JQuery.d.ts
// 定義類型命名空間
declare namespace JQuery {
type Selector = string;
type TheTypeOrArray <T> = T | T[];
type htmlString = string;
}
// 定義接口
interface JQuery<TElement = HTMLElement> extends Iterable<TElement> {
length: number;
// 重載
add(select: JQuery.Selector, context: Element): this;
add(select: JQuery.Selector | JQuery.TheTypeOrArray<Element> | JQuery.htmlString | JQuery): this;
children(selector?: JQuery.Selector): this;
css(propertyName: string): string;
html(): string;
empty(): this;
end(): this;
eq(index: number): this;
}
// 導出
export default JQuery;
複製代碼
jQuery 的類型聲明文件源碼沒有這麼簡單,這裏作了下簡化,以便使用。typescript
類型聲明文件(*.d.ts
)中,咱們編寫的就是類型定義了,可使用 type
、class
和 interface
。npm
// type.ts
// 基本
type FirstName = string;
// 賦值
type LastName = FirstName;
// 對象
type Developer = {
name: string;
age: number;
}
// 方法
type showName = (name: string) => string;
複製代碼
// class.ts
// 類
class Developer2 {
name: string;
age: number;
showName: (name: string) => string;
}
複製代碼
// interface.ts
// 接口
interface Option {
init(): void;
get(str: string): object;
}
複製代碼
type
(或class
)使用場景是 Typescript 的基本類型不知足需求的時候,經過定義自定義類型來組合新類型;interface
是對外輸出接口,對外;爲 xxx.d.ts
建立變量,就是說在頂層上定義。編輯器
// declare.ts
declare var age: number;
declare function showAge(age: number): void;
declare class DeveloperClass {
name: string;
}
declare namespace DeveloperNs {
interface skills {
code(): void;
}
}
複製代碼
//
{
"basketball": {
name: "籃球",
people: 5
},
"footerball": {
name: "足球"
people: 11
}
}
複製代碼
分析上面的數據接口,可看出屬性名 basketball
和 footerball
是動態的,所以工具
// dynamicAttributes.ts
interface BallAttr {
name: string;
people: number;
}
interface Ball {
[ball: string]: BallAttr
}
複製代碼
// typeList.ts
type BallSelect = 'basketball' | 'footerball';
interface BallAttr {
name: string;
people: number;
}
type Ball2 = {
[ball in BallSelect]: BallAttr
}
複製代碼
單純查看一個包或想查下本身要發的包是否有重名,可到 TypeSearch 尋結果。
說到發佈,一般是這兩種方式。
就是與 npm 包綁定一塊兒,通常存放在根目錄的 types
下,使用方下載完依賴包後悔自動檢測並識別類型聲明文件。
用於擴展 javascript 庫的類型聲明文件,其安裝方式和 npm 包稍有不一樣 npm install @types/xxx --save-dev
。
若是你想讓本身寫的類型聲明文件包發佈到 @types 社區,可在 DefinitelyTyped 提交一個 pull request。對於 @types 社區 下的包都是從 DefinitelyTyped 自動發佈出去的,這裏用到工具 types-publisher。
types
├── a.d.ts
├── b.d.ts
├── xxx.d.ts
├── index.d.ts # 入口模塊
└── z.d.ts
複製代碼
子模塊沒必要定義命名空間,外部環境就獲取不到(types
目錄除外)。
// a.d.ts
export interface AInterface {
name: string;
}
// b.d.ts
export interface BInterface {
name: string;
}
// xxx.d.ts
export interface XXXInterface {
name: string;
}
// z.d.ts
export interface ZInterface {
name: string;
}
複製代碼
入口文件(定義命名空間和導出子模塊)
// index.d.ts
import * as AModule from './a';
import * as BModule from './b';
import * as XXXModule from './xxx';
import * as ZModule from './z';
declare namespace Index {
export type AInterface = AModule.AInterface;
export type BInterface = BModule.BInterface;
export type XXXInterface = XXXModule.XXXInterface;
export type ZInterface = ZModule.ZInterface;
}
複製代碼