Начало работы с Typescript в 2019 году

внешний интерфейс TypeScript

banner

на основеОпрос разработчиков Stack Overflow за 2018 г.,TypeScriptБолее «любимый» как язык программирования, чем JavaScript. Причина, по которой TypeScript так популярен среди разработчиков js, заключается в следующем: типы, добавленные в javascript, помогают вам находить ошибки (код) до запуска кода. Ошибки, предоставляемые компилятором TypeScript, могут быть хорошим руководством по исправлению ошибок в вашем коде. Добавление типов в javascript также помогает редактору кода предоставлять расширенные функции, такие как завершение кода, рефакторинг всего проекта и автоматический импорт модулей.

more loved programming languages

Если вы думаете, что TypeScript — это совершенно новый язык программирования, его изучение может быть пугающим. Однако TypeScript — это просто дополнительный уровень (надмножество) JavaScript, и вам не нужно понимать каждый синтаксис TypeScript перед его использованием. TypeScript позволяет вам изменить расширение файла,.jsдля.tsчтобы легко конвертировать файлы javascript, и весь код будет правильно компилироваться как TypeScript. Если вы хотите обеспечить более широкий процент охвата типов в ваших файлах TypeScript, вы можете настроить TypeScript так, чтобы он был более строгим, что вы можете сделать после того, как познакомитесь с языком.

Цель этой статьи — быстро провести вас через 95 % сценариев, с которыми вы столкнетесь в стандартном проекте TypeScript. Остальные 5% вы можете поискать в Google, а внизу этого поста я размещу несколько полезных ссылок на ресурсы TypeScript.

Настроить TypeScript

Конечно, чтобы начать писать TypeScript (файлы), которые правильно компилируются, необходимо правильно настроить среду разработки.

1. Установите компилятор TypeScript

Во-первых, чтобы иметь возможность конвертировать файлы TypeScript в файлы JavaScript, нам нужно установить компилятор TypeScript. Установка TypeScript может быть установлена ​​глобально (установлена ​​в файловой системе, доступна где угодно) или локально (доступна только на уровне проекта). [Личное предпочтение последнему]

# NPM Installation Method
npm install --global typescript # Global installation
npm install --save-dev typescript # Local installation

# Yarn Installation Method
yarn global add typescript # Global installation
yarn add --dev typescript # Local installation

2. Убедитесь, что ваш редактор поддерживает TypeScript

Вам нужно убедиться, что ваш редактор правильно настроен для использования TypeScript. Например, чтобы лучше использовать TypeScript в редакторе, вам нужно установить плагин (если вы используете атом, вы можете установить atom-typescript). если вы используетеVS Code编辑器, то вам не нужно устанавливать дополнительные плагины, потому что он имеет встроенную поддержку TypeScript. 😎

3. Создайте новый файл tsconfig.json.

Файл tsconfig.json используется для настройки параметров проекта TypeScript. Он должен быть размещен в проектеКорневая директориясередина. Этот файл позволяет настроить компилятор TypeScript с различными параметрами.

Если вы просто хотите, чтобы TypeScript работал, вам нужно только включить пустой объект JSON в файл tsconfig.json, но если вы хотите, чтобы компилятор TypeScript вел себя по-другому (например, вывод скомпилированных файлов JavaScript в определенный выходной каталог)), вы можно прочитать больше (контент) о том, какие параметры можно настроить.

Примечание: вы также можете запуститьtsc --initдля создания файла tsconfig.json с некоторыми заданными для вас параметрами по умолчанию и некоторыми другими параметрами, которые закомментированы.

4. Преобразование TypeScript в JavaScript

Чтобы преобразовать ваш код TypeScript в код JavaScript, вам нужно запустить в консоликоманда tsc. Запуск команды tsc укажет компилятору TypeScript искатьtsconfig.jsonфайл, который определит корневой каталог проекта, а также скомпилирует TypeScript и.tsфайл преобразован в.jsопции для файлов.

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

Например, файл TypeScript выглядит следующим образом...

const greeting = (person: string) => {
    console.log('Good day ' + person);
};
greeting('Daniel');

должен быть преобразован в следующий файл JavaScript...

var greeting = function(person) {
    console.log('Good day ' + person);
};
greeting('Daniel');

Если вы хотите, чтобы компилятор TypeScript (динамически) следил за изменениями содержимого файлов TypeScript и автоматически.tsфайл преобразован в.jsфайл, который вы можете запустить в репозитории вашего проекта (командная строка)tsc -p.

В VS-коде вы можете использовать⌘⇧БВызывает меню, которое (включает) запускает программу преобразования в обычном режиме и режиме мониторинга (соответственноtsc:buildа такжеtsc:watch).

vs code build tasks menu

Узнайте о статической и динамической типизации

JavaScript поставляется с 7 динамическими типами:

  • Undefined
  • Null
  • Boolean
  • Number
  • String
  • Symbol
  • Object

Вышеупомянутые типы называются динамическими типами, поскольку они используются во время выполнения.

TypeScript привносит статическую типизацию в язык JavaScript, и эти типы определяются во время компиляции (без запуска кода). Статическая типизация может прогнозировать динамически типизированные значения, что может помочь предупредить вас о возможных ошибках без необходимости запуска кода.

базовый статический тип

Что ж, давайте углубимся в синтаксис TypeScript. Ниже приведены наиболее распространенные типы в TypeScript.

Примечание. Я не упомянул типы never и object, потому что, по моему опыту, они используются не очень часто.

boolean

ты уже знаешьtrueа такжеfalseстоило того.

let isAwesome: boolean = true;

string

Текстовые данные заключаются в одинарные кавычки (''), двойные кавычки ("") или завершающие токены (``) [также известные как символы шаблона].

let name: string = 'Chris';
let breed: string = 'Border Collie';

Если вы используете флаг after, строка называетсяТекст шаблона, в него можно вставлять выражения.

let punchline: string = 'Because it was free-range.';
let joke: string = `
    Q: Why did the chicken cross the road?
    A: ${punchline}
`;

number

Любое число с плавающей запятой задается как числовой тип. Как часть TypeScript поддерживаетсяЧетыре типа числовых литераловбывают двоичными, десятичными, восьмеричными и шестнадцатеричными.

let decimalNumber: number = 42;
let binaryNumber: number = 0b101010; // => 42
let octalNumber: number = 0o52; // => 42
let hexadecimalNumber: number = 0x2a; // => 42

Примечание. Вы не одиноки в путанице двоичных, восьмеричных и шестнадцатеричных чисел.

array

В TypeScript есть два способа записи типов массивов. Первый — это суффикс [] в типе элемента массива, который необходимо найти.

let myPetFamily: string[] = ['rocket', 'fluffly', 'harry'];

Другой альтернативой является Array, за которым следует тип элемента массива, который вы ищете.ArrayТип (заключается в угловые скобки).

let myPetFamily: Array<string> = ['rocket', 'fluffly', 'harry'];

tuple

Кортеж — это массив, содержащий фиксированное количество элементов и связанных типов.

let myFavoriteTuple: [string, number, boolean];
myFavoriteTuple = ['chair', 20, true]; // ✅
myFavoriteTuple = [5, 20, true]; // ❌ - The first element should be a string, not a number

enum

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

По умолчанию перечислениям присваиваются значения, начинающиеся с 0, и последующие значения (предыдущее значение перечисления) плюс 1.

enum Sizes {
    Small,
    Medium,
    Large,
}
Sizes.Small; // => 0
Sizes.Medium; // => 1
Sizes.Large; // => 2

Первое значение также может быть установлено на значение, отличное от 0.

enum Sizes {
    Small = 1,
    Medium,
    Large,
}
Sizes.Small; // => 1
Sizes.Medium; // => 2
Sizes.Large; // => 3

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

enum ThemeColors {
    Primary = 'primary',
    Secondary = 'secondary',
    Dark = 'dark',
    DarkSecondary = 'darkSecondary',
}

any

Если тип переменной неизвестен, и мы не хотим, чтобы средство проверки типов жаловалось во время компиляции, мы можем использоватьanyТипы.

let whoKnows: any = 4; // assigned a number
whoKnows = 'a beautiful string'; // can be reassigned to a string
whoKnows = false; // can be reassigned to a boolean

Когда вы начинаете использовать TypeScript, он может использоваться частоanyТипы. Однако лучше попытаться уменьшитьany, потому что TypeScript менее полезен, когда компилятор не знает тип, связанный с переменной.

void

Когда нет никакого типа, связанного с вещью,voidСледует использовать тип. Чаще всего он используется при указании возвращаемого значения функции, которая ничего не возвращает.

const darkestPlaceOnEarth = (): void => {
    console.log('Marianas Trench');
};

нулевой и неопределенный

И null, и undefined соответствуют типам значений null и undefined, которые вы видите в javascript. Эти типы не очень полезны при использовании по отдельности.

let anUndefinedVariable: undefined = undefined;
let aNullVariable: null = null;

По умолчанию типы null и undefined являются подтипами других типов, что означает, что переменным строкового типа можно присвоить значение null или undefined. Обычно это неразумное поведение, поэтому обычно рекомендуетсяtsconfig.jsonДля параметра компилятора strictNullChecks в файле задано значение true. Установка для strictNullChecks значения true приводит к тому, что значения null и undefined должны быть явно установлены для типа переменной.

вывод типа

К счастью, вам не нужно указывать типы по всему меню в вашем коде, потому что TypeScript имеет вывод типа. Вывод типа - это то, что компилятор Tymdercript использует для определения типа (содержимого).

вывод базового типа

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

// Variable initialization
let x = 10; // x is given the number type

В приведенном выше примереxприсвоен номер, TypeScript начнется сnumberтип будетxпеременные связаны.

// Default function parameters
const tweetLength = (message = 'A default tweet') => {
    return message.length;
};

В приведенном выше примере параметру сообщения присваивается значение по умолчанию типа строка, поэтому компилятор TypeScript сделает вывод, что тип сообщения является строкой, поэтому при доступе к свойству длины не будет выдана ошибка компиляции.

function add(a: number, b: number) {
    return a + b;
}
const result = add(2, 4);
result.toFixed(2); // ✅
result.length; // ❌ - length is not a property of number types

В приведенном выше примере, поскольку TypeScript сообщаетaddфункция, ее параметрыnumberтип, то можно сделать вывод, что возвращаемый тип также должен бытьnumber.

Лучший вывод универсального типа

При выводе типов из нескольких возможных типов TypeScript используетЛучший универсальный типАлгоритмы выбираются для всех других типов кандидатов.

let list = [10, 22, 4, null, 5];
list.push(6); // ✅
list.push(null); // ✅
list.push('nope'); // ❌ - type 'string' is neither of type 'number' or 'null'

В приведенном выше примере массив (список) состоит изnumberилиnullтипов, поэтому TypeScript ожидает толькоnumberилиnullВ массив добавляется значение типа.

введите аннотацию

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

базовый тип

в (выше)базовый статический типВо введении к главе используются все типы:за которым следует имя типа для объявления.

let aBoolean: boolean = true;
let aNumber: number = 10;
let aString: string = 'woohoo';

Arrays

упоминается в (выше)arrayВ разделе «Типы» массивы можно аннотировать одним из двух способов.

// First method is using the square bracket notation
let messageArray: string[] = ['hello', 'my name is fred', 'bye'];

// Second method uses the Array keyword notation
let messageArray: Array<string> = ['hello', 'my name is fred', 'bye'];

интерфейс

Одним из способов объединения нескольких типов аннотаций является использование интерфейсов.

interface Animal {
    kind: string;
    weight: number;
}
let dog: Animal;
dog = {
    kind: 'mammal',
    weight: 10,
}; // ✅
dog = {
    kind: true,
    weight: 10,
}; // ❌ - kind should be a string

введите псевдоним

TypeScript использует Type Alias ​​для указания нескольких аннотаций типов, что (несколько) сбивает с толку. [упомянуто ниже]

type Animal = {
    kind: string;
    weight: number;
};
let dog: Animal;
dog = {
    kind: 'mammal',
    weight: 10,
}; // ✅
dog = {
    kind: true,
    weight: 10,
}; // ❌ - kind should be a string

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

Если вы хотите узнать больше оtype aliasа такжеinterfaceДля сравнения рекомендую посмотреть книгу Мартина Хохеля.эта статья.

Встроенные комментарии

Вместо создания повторно используемого интерфейса иногда может быть более подходящим встроить аннотированные типы.

let dog: {
    kind: string;
    weight: number;
};
dog = {
    kind: 'mammal',
    weight: 10,
}; // ✅
dog = {
    kind: true,
    weight: 10,
}; // ❌ - kind should be a string

Дженерики

В некоторых случаях конкретный тип переменной не имеет значения, но должен обеспечивать связь между различными переменными и типами. В этих случаях следует использовать универсальный тип.

const fillArray = <T>(len: number, elem: T) => {
    return new Array<T>(len).fill(elem);
};
const newArray = fillArray<string>(3, 'hi'); // => ['hi', 'hi', 'hi']
newArray.push('bye'); // ✅
newArray.push(true); // ❌ - only strings can be added to the array

В приведенном выше примере есть общий типT, что соответствует переходу кfillArrayВторой тип параметра функции. Перейти кfillArrayВторым параметром функции является строка, поэтому в созданном массиве все элементы имеют строковый тип.

Следует отметить, что по соглашению для универсальных типов используется одна (верхняя) буква (например:TилиK). Однако вы не ограничены в использовании более описательных имен для ваших универсальных типов. В следующем примере используются более описательные имена для предоставленных универсальных типов:

const fillArray = <ArrayElementType>(len: number, elem: ArrayElementType) => {
    return new Array<ArrayElementType>(len).fill(elem);
};
const newArray = fillArray<string>(3, 'hi'); // => ['hi', 'hi', 'hi']
newArray.push('bye'); // ✅
newArray.push(true); // ❌ - only strings can be added to the array

тип союза

В случае, когда тип может быть одним из многих типов, используйте|Разделитель разделяет параметры разных типов для использования типов объединения.

// The `name` parameter can be either a string or null
const sayHappyBirthdayOnFacebook = (name: string | null) => {
    if (name === null) {
        console.log('Happy birthday!');
    } else {
        console.log(`Happy birthday ${name}!`);
    }
};
sayHappyBirthdayOnFacebook(null); // => "Happy birthday!"
sayHappyBirthdayOnFacebook('Jeremy'); // => "Happy birthday Jeremy!"

тип перекрестка

Использование типов пересечения&Символы объединяют несколько типов. Это отличается от типов объединения (выше), потому что типы объединения представляютТип результата является одним из перечисленных типов, пока тип пересечения представляетТип результата - это набор всех перечисленных типов.

type Student = {
    id: string;
    age: number;
};
type Employee = {
    companyId: string;
};
let person: Student & Employee;
person.age = 21; // ✅
person.companyId = 'SP302334'; // ✅
person.id = '10033402'; // ✅
person.name = 'Henry'; // ❌ - name does not exist in Student & Employee

тип кортежа

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

let list: [string, string, number];
list = ['apple', 'banana', 8.75]; // ✅
list = ['apple', true, 8.75]; // ❌ - the second argument should be of type string
list = ['apple', 'banana', 10.33, 3]; // ❌ - the tuple specifies a length of 3, not 4

необязательный тип

Могут быть случаи, когда параметры функции или свойства объекта являются необязательными. В этих случаях используйте?для представления этих необязательных значений.

// Optional function parameter
function callMom(message?: string) {
    if (!message) {
        console.log('Hi mom. Love you. Bye.');
    } else {
        console.log(message);
    }
}
// Interface describing an object containing an optional property
interface Person {
    name: string;
    age: number;
    favoriteColor?: string; // This property is optional
}

полезные ресурсы

Для содержимого TypeScript, не описанного в этой статье, я рекомендую следующие ресурсы.

TypeScript Handbook (Official TypeScript docs)

TypeScript Deep Dive (Online TypeScript Guide)

Understanding TypeScript's Type Annotation (Great introductory TypeScript article)

Оригинальная ссылкаWoohoo.Robert Cooper.What/Individual-started…

Статья впервые опубликованаGitHub.com/still99/блог…

больше контентаGitHub.com/still99/блог…