Перейти к содержанию

Функции

Система типов TypeScript уделяет большое внимание функциям, ведь они являются основными строительными блоками нашей составной системы.

Описание параметров

Конечно, вы можете описывать типы параметров функции так же, как вы можете описываете типы других переменных:

1
2
3
4
5
// описание переменной
var sampleVariable: { bar: number };

// описание параметра функции
function foo(sampleParameter: { bar: number }) {}

Здесь я использовал встроенные описания типа. Конечно, вы можете использовать интерфейсы и т. д.

Описание типа возврата

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

1
2
3
4
5
6
7
8
interface Foo {
    foo: string;
}

// Тип для описания возвращаемого функцией значения `: Foo`
function foo(sample: Foo): Foo {
    return sample;
}

Да, я использовал здесь интерфейс, но вы можете использовать другие описания, например, встроенные описания.

Как правило, вам не нужно описывать тип возвращаемого функцией значения, так как он может быть автоматически распознан компилятором.

1
2
3
4
5
6
7
interface Foo {
    foo: string;
}

function foo(sample: Foo) {
    return sample; // распознан тип возвращаемого значения 'Foo'
}

Однако, как правило, рекомендуется добавлять эти описания типов для устранения ошибок, например:

1
2
3
4
5
6
function foo() {
    return { fou: 'John Doe' }; // Возможно, вы не сможете найти эту опечатку
    // `foo`, пока не станет слишком поздно
}

sendAsJSON(foo());

Если вы не планируете возвращать что-либо из функции, вы можете описать ее как :void, но как правило вы можете опустить :void.

Необязательные параметры

Вы можете пометить параметр как необязательный:

1
2
3
4
5
6
function foo(bar: number, bas?: string): void {
    // ..
}

foo(123);
foo(123, 'hello');

В качестве альтернативы вы можете даже предоставить значение по умолчанию (используя = someValue после объявления параметра), которое будет использоваться если при вызове не было предоставлено иного значения этого параметра:

1
2
3
4
5
6
function foo(bar: number, bas: string = 'hello') {
    console.log(bar, bas);
}

foo(123); // 123, hello
foo(123, 'world'); // 123, world

Перегрузки

TypeScript позволяет объявлять перегрузки функций. Это полезно для документации + проверки типов. Рассмотрим следующий код:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function padding(
    a: number,
    b?: number,
    c?: number,
    d?: any
) {
    if (
        b === undefined &&
        c === undefined &&
        d === undefined
    ) {
        b = c = d = a;
    } else if (c === undefined && d === undefined) {
        c = a;
        d = b;
    }
    return {
        top: a,
        right: b,
        bottom: c,
        left: d,
    };
}

Если вы внимательно посмотрите на код, вы поймете значения a,b,c,d меняются в зависимости от количества переданных параметров. Также функция ожидает только 1, 2 либо 4 параметра. Эти ограничения могут быть обеспечены и задокументированы с использованием перегрузки функций. По сути через условие вы просто объявляете параметры функции несколько раз. Последние объявленные параметры - это те, которые действительно используются внутри тела функции, но недоступные извне.

Это показано ниже:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
// Перегрузки
function padding(all: number);
function padding(
    topAndBottom: number,
    leftAndRight: number
);
function padding(
    top: number,
    right: number,
    bottom: number,
    left: number
);
// Практическая реализация содержащая все случаи, которые должно обрабатывать
// тело функции
function padding(
    a: number,
    b?: number,
    c?: number,
    d?: number
) {
    if (
        b === undefined &&
        c === undefined &&
        d === undefined
    ) {
        b = c = d = a;
    } else if (c === undefined && d === undefined) {
        c = a;
        d = b;
    }
    return {
        top: a,
        right: b,
        bottom: c,
        left: d,
    };
}

Здесь первые три случая использования параметров доступны как допустимые вызовы padding:

1
2
3
4
5
padding(1); // Okay: все
padding(1, 1); // Okay: topAndBottom, leftAndRight
padding(1, 1, 1, 1); // Okay: top, right, bottom, left

padding(1, 1, 1); // Ошибка: Не входит в число доступных перегрузок

Конечно, важно, чтобы последнее объявление (истинное объявление, видимое внутри функции) было совместимо со всеми перегрузками. Потому что это важный смысл вызовов функций, которые тело функции должно учитывать.

Перегрузка функций в TypeScript не приводит к увеличению нагрузки во время выполнения. Она просто позволяет документировать как функция будет вызываться, а компилятор контролирует оставшуюся часть кода.

Комментарии