TypeScript 聲明文件規(guī)范

2022-03-25 09:04 更新

TypeScript聲明文件規(guī)范

普通類型

Number,String,BooleanObject

不要使用如下類型Number,String,BooleanObject。 這些類型指的是非原始的裝盒對象,它們幾乎沒在JavaScript代碼里正確地使用過。

/* 錯(cuò)誤 */
function reverse(s: String): String;

應(yīng)該使用類型numberstring,and boolean。

/* OK */
function reverse(s: string): string;

如果你就要使用Object類型,考慮使用any代替。 目前在TypeScript里無法指定一個(gè)對象“不是一個(gè)原始值”。

泛型

不要定義一個(gè)從來沒使用過其類型參數(shù)的泛型類型。 了解詳情 TypeScript FAQ page。

回調(diào)函數(shù)類型

回調(diào)函數(shù)返回值類型

不要為返回值被忽略的回調(diào)函數(shù)設(shè)置一個(gè)any類型的返回值類型:

/* 錯(cuò)誤 */
function fn(x: () => any) {
    x();
}

應(yīng)該給返回值被忽略的回調(diào)函數(shù)設(shè)置void類型的返回值類型:

/* OK */
function fn(x: () => void) {
    x();
}

為什么:使用void相對安全,因?yàn)樗乐沽四悴恍⌒氖褂?code>x的返回值:

function fn(x: () => void) {
    var k = x(); // oops! meant to do something else
    k.doSomething(); // error, but would be OK if the return type had been 'any'
}

回調(diào)函數(shù)里的可選參數(shù)

不要在回調(diào)函數(shù)里使用可選參數(shù)除非你真的要這么做:

/* 錯(cuò)誤 */
interface Fetcher {
    getObject(done: (data: any, elapsedTime?: number) => void): void;
}

這里有一種特殊的意義:done回調(diào)函數(shù)可能以1個(gè)參數(shù)或2個(gè)參數(shù)調(diào)用。 代碼大概的意思是說這個(gè)回調(diào)函數(shù)不在乎是否有 elapsedTime參數(shù), 但是不需要把這個(gè)參數(shù)當(dāng)成可選參數(shù)來達(dá)到此目的 -- 因?yàn)榭偸窃试S提供一個(gè)接收較少參數(shù)的回調(diào)函數(shù)。

應(yīng)該寫出回調(diào)函數(shù)的非可選參數(shù):

/* OK */
interface Fetcher {
    getObject(done: (data: any, elapsedTime: number) => void): void;
}

重載與回調(diào)函數(shù)

不要因?yàn)榛卣{(diào)函數(shù)參數(shù)個(gè)數(shù)不同而寫不同的重載:

/* 錯(cuò)誤 */
declare function beforeAll(action: () => void, timeout?: number): void;
declare function beforeAll(action: (done: DoneFn) => void, timeout?: number): void;

應(yīng)該只使用最大參數(shù)個(gè)數(shù)寫一個(gè)重載:

/* OK */
declare function beforeAll(action: (done: DoneFn) => void, timeout?: number): void;

為什么:回調(diào)函數(shù)總是可以忽略某個(gè)參數(shù)的,因此沒必要為參數(shù)少的情況寫重載。 參數(shù)少的回調(diào)函數(shù)首先允許錯(cuò)誤類型的函數(shù)被傳入,因?yàn)樗鼈兤ヅ涞谝粋€(gè)重載。

函數(shù)重載

順序

不要把一般的重載放在精確的重載前面:

/* 錯(cuò)誤 */
declare function fn(x: any): any;
declare function fn(x: HTMLElement): number;
declare function fn(x: HTMLDivElement): string;

var myElem: HTMLDivElement;
var x = fn(myElem); // x: any, wat?

應(yīng)該排序重載令精確的排在一般的之前:

/* OK */
declare function fn(x: HTMLDivElement): string;
declare function fn(x: HTMLElement): number;
declare function fn(x: any): any;

var myElem: HTMLDivElement;
var x = fn(myElem); // x: string, :)

為什么:TypeScript會選擇第一個(gè)匹配到的重載當(dāng)解析函數(shù)調(diào)用的時(shí)候。 當(dāng)前面的重載比后面的“普通”,那么后面的被隱藏了不會被調(diào)用。

使用可選參數(shù)

不要為僅在末尾參數(shù)不同時(shí)寫不同的重載:

/* 錯(cuò)誤 */
interface Example {
    diff(one: string): number;
    diff(one: string, two: string): number;
    diff(one: string, two: string, three: boolean): number;
}

應(yīng)該盡可能使用可選參數(shù):

/* OK */
interface Example {
    diff(one: string, two?: string, three?: boolean): number;
}

注意這在所有重載都有相同類型的返回值時(shí)會不好用。

為什么:有兩種生要的原因。

TypeScript解析簽名兼容性時(shí)會查看是否某個(gè)目標(biāo)簽名能夠使用源的參數(shù)調(diào)用, 且允許外來參數(shù)。 下面的代碼暴露出一個(gè)bug,當(dāng)簽名被正確的使用可選參數(shù)書寫時(shí):

function fn(x: (a: string, b: number, c: number) => void) { }
var x: Example;
// When written with overloads, OK -- used first overload
// When written with optionals, correctly an error
fn(x.diff);

第二個(gè)原因是當(dāng)使用了TypeScript“嚴(yán)格檢查null”特性時(shí)。 因?yàn)闆]有指定的參數(shù)在JavaScript里表示為undefined,通常顯示地為可選參數(shù)傳入一個(gè)undefined。 這段代碼在嚴(yán)格null模式下可以工作:

var x: Example;
// When written with overloads, incorrectly an error because of passing 'undefined' to 'string'
// When written with optionals, correctly OK
x.diff("something", true ? undefined : "hour");

使用聯(lián)合類型

不要為僅在某個(gè)位置上的參數(shù)類型不同的情況下定義重載:

/* WRONG */
interface Moment {
    utcOffset(): number;
    utcOffset(b: number): Moment;
    utcOffset(b: string): Moment;
}

應(yīng)該盡可能使用聯(lián)合類型:

/* OK */
interface Moment {
    utcOffset(): number;
    utcOffset(b: number|string): Moment;
}

注意我們沒有讓b成為可選的,因?yàn)楹灻姆祷刂殿愋筒煌?/p>

為什么:This is important for people who are "passing through" a value to your function:

function fn(x: string): void;
function fn(x: number): void;
function fn(x: number|string) {
    // When written with separate overloads, incorrectly an error
    // When written with union types, correctly OK
    return moment().utcOffset(x);
}
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號