Table of Contents #

Основные типы #

Number, String, Boolean, и Object

Никогда не используйте типы Number, String, Boolean или Object. Эти типы ссылаются на непримитивные упакованные типы, которые почти никогда не используются в JavaScript-коде.

/* НЕПРАВИЛЬНО */
function reverse(s: String): String;

Используйте типы number, string и boolean.

/* ПРАВИЛЬНО */
function reverse(s: string): string;

Если вам хочется применить тип Object, используйте вместо него any. На данный момент в TypeScript нет способа указать, что объект должен быть "непримитивным".

Обобщения

Никогда не создавайте обобщенный тип, который не использует типовый параметр. Больше информации на странице часто задаваемых вопросов.

Типы функций обратного вызова #

Типы возвращаемых значений функций обратного вызова

Не используйте any в качестве типа возвращаемого значения для функций обратного вызова, чье возвращаемое значение игнорируется:

/* НЕПРАВИЛЬНО */
function fn(x: () => any) {
    x();
}

Используйте тип void в подобных случаях:

/* ПРАВИЛЬНО */
function fn(x: () => void) {
    x();
}




Почему: использование void более безопасно, поскольку защищает от случайного использования возвращаемого значения x без проверки типов:

function fn(x: () => void) {
    var k = x(); // упс! планировалось написать что-то другое
    k.doSomething(); // ошибка, но все было бы нормально, если бы тип возвращаемого значения был 'any'
}

Необязательные параметры в функциях обратного вызова

Не используйте необязательные параметры в функциях обратного вызова, кроме случаев, когда они необходимы:

/* НЕПРАВИЛЬНО */
interface Fetcher {
    getObject(done: (data: any, elapsedTime?: number) => void): void;
}

Это имеет следующее значение: функция обратного вызова done может быть вызвана либо с одним, либо с двумя аргументами. Разработчик, вероятно, намеревался выразить то, что функция обратного вызова может не обращать внимания на параметр elapsedTime, однако для этого не нужно делать параметр необязательным -- передача функции обратного вызова, которая принимает меньшее число аргументов, всегда допускается.

Всегда используйте обязательные параметры для функции обратного вызова:

/* ПРАВИЛЬНО */
interface Fetcher {
    getObject(done: (data: any, elapsedTime: number) => void): void;
}

Перегрузки и функции обратного вызова

Не создавайте отдельных перегрузок, различающихся только числом аргументов у функции обратного вызова:

/* НЕПРАВИЛЬНО */
declare function beforeAll(action: () => void, timeout?: number): void;
declare function beforeAll(action: (done: DoneFn) => void, timeout?: number): void;

Создавайте одну общую перегрузку с максимальным числом аргументов:

/* ПРАВИЛЬНО */
declare function beforeAll(action: (done: DoneFn) => void, timeout?: number): void;

Почему: функция с меньшим числом параметров всегда допустима, поэтому необходимости в более короткой перегрузке нет. Добавление в начало варианта с более короткой перегрузкой приводит к тому, что неподходящие по типу функции будут допускаться, поскольку подходят к первой перегрузке.

Перегрузки функций #

Упорядочивание

Не помещайте более общие перегрузки перед более специфичными:

/* НЕПРАВИЛЬНО */
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?

Сортируйте перегрузки так, чтобы более общие находились после более специфичных:

/* ПРАВИЛЬНО */
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 выбирает первую подходящую перегрузку. Если первая перегрузка является более общей, чем последующие, то последующие перегрузки оказываются скрыты и не могут быть вызваны.

Используйте необязательные параметры

Не создавайте несколько перегрузок, отличающихся только конечными аргументами:

/* НЕПРАВИЛЬНО */
interface Moment {
    diff(b: MomentComparable): number;
    diff(b: MomentComparable, unitOfTime: string): number;
    diff(b: MomentComparable, unitOfTime: string, round: boolean): number;
}

Используйте необязательные параметры, если это возможно:

/* ПРАВИЛЬНО */
interface Moment {
    diff(b: MomentComparable, unitOfTime?: string, round?: boolean): number;
}

Обратите внимание, что подобное "схлопывание" возможно только если у всех перегрузок один и тот же тип возвращаемого значения.

Почему: Это важно по двум причинам.

TypeScript определяет совместимость сигнатур, определяя, может ли какая-либо сигнатура цели вызвана с аргументами исходной сигнатуры, причем лишние аргументы допускаются. Следующий код, например, позволяет обнаружить ошибку только в том случае, если сигнатура правильно записана с использованием необязательных параметров:

function fn(x: (a: string, b: number, c: number) => void) { }
var x: Moment;
// Если записано с перегрузками, все нормально -- использована первая перегрузка
// Если записано с необязательными параметрами, обнаруживается ошибка
fn(x.diff);

Вторая причина -- применение к коду, использующему библиотеку, "строгой проверки на null". Поскольку пропущенные параметры для JavaScript выглядят как undefined, то, как правило, функции с необязательными параметрами можно явно передать undefined. Следующий код, например, должен компилироваться при строгой проверке на null:

var x: Moment;
// Если записано с перегрузками, то несправедливая ошибка, так как передается 'undefined' вместо 'string'
// Если записано с необязательными параметрами, то все нормально
x.diff(something, someOtherThing ? undefined : "hour");

Используйте объединения

Не создавайте перегрузок, которые отличаются только типом одного аргумента:

/* НЕПРАВИЛЬНО */
interface Moment {
    utcOffset(): number;
    utcOffset(b: number): Moment;
    utcOffset(b: string): Moment;
}

Используйте объединения, если это возможно:

/* ПРАВИЛЬНО */
interface Moment {
    utcOffset(): number;
    utcOffset(b: number|string): Moment;
}

Обратите внимание, что параметр b не сделан необязательным, так как типы возвращаемых значений различаются.

Почему: Это важно для тех, кто передает значения "сквозь" функцию:

function fn(x: string): void;
function fn(x: number): void;
function fn(x: number|string) {
    // Если записано с отдельными перегрузками, то несправедливая ошибка
    // Если записано с объединениями, то все нормально
    return moment().utcOffset(x);
}

Источник






Поддержите перевод документации:



Поддерживатель | Github Репозиторий


Documentation generated by mdoc.
Молния! Обновления, новости и статьи Typescript.