Полезные фичи

Тут собраны общие полезные фичи TypeScript

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

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

function getSmth(value: string): string;
function getSmth(value: number): number;
function getSmth(value: any): any {
  if (typeof value === 'string') {
    console.log('function that return a string');
    return '4815162342';
  } else {
    console.log('function that return a number');
    return 4815162342
  }
}

const firstResult = getSmth(0);
const secondResult = getSmth('0');

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

Generics

Эту фичу мне удобнее называть как шаблоны. По аналогии с C++ тут есть шаблонные функции и шаблонные классы, которые принимают дополнительный параметр - тип данных. Покажу на примере :

class Vector<Type> {
  
  private items: Type[] = [];

  public push(item: Type): void {
    this.items.push(item);
  }

  public pop(): void {
    this.items.pop();
  }

  public printVector(): void {
    for(let item of this.items) {
      console.log(item);
    }
  }
}

const strings = new Vector<string>();

strings.push('qwerty');
strings.push('zxcvbn');
strings.push('asdfgh');
strings.printVector(); // qwerty zxcvbn asdfgh

Enum

Перечисления, удобная фича, позволяет создавать константы в виде перечислений.

Namespaces

Клёвая фича с пространством имён. Если есть какие-то однотипные сущности, которые импортируются из каких-либо модулей, то можно запаковать их в пространство имён и импортировать оттуда.

namespace StringValidators {
  export const required = (string: string): boolean => {
    return !!string;
  }
  export const length = (string: string, value): boolean => {
    return string.length >= value;
  }
}

const string = 'qwerty';

if (StringValidators.required(string) && StringValidators.length(string, 10)) {
  console.log('string is valid');
} else {
  console.log('string is invalid'); // string is invalid
}

Как видим мы запаковали валидаторы для строк, и валидатор на длину строки выдал ошибку, как и предполагалось.

Implements вместо extend

Увидел в одном примере интересный момент. Как мы все в курсе - JavaScript отказался от множественного наследования в стандарте ES6, как и от интерфейсов в абстрактными классами, однако наш TypeScript предоставляет почти все эти возможности. Напомню что TS даёт нам интерфейсы и абстрактные классы, но множественного наследования так и нет, однако известно что можно осуществить множественную реализацию интерфейсов. Вот собственно пример(максимально упростил) :

class a {}

class b {}

class c implements a, b {}

Как видим a и b это не интерфейсы а классы. Так что же здесь происходит? Дело в том что TS рассматривает эти классы подобно интерфейсам, обращая внимание только на их типизацию игнорируя реализацию. Таким образом всё что если в этих классах нужно будет реализовать в производном классе.

В официальных доках по TypeScript эта фича называется Mixins.

Interfaces inheritance

Наследование интерфейсов, полезно если есть необходимость в расширении одного интерфейса другим. Это можно выполнить используя ключевое слово extends в объявлении интерфейса.

Last updated

Was this helpful?