На горизонте появится TypeScript 3.0, а вместе с ним и несколько долгожданных обновлений, которые, к сожалению, не сравнятся с фальсифицированной шумихой #smooshgate.

Изучив анонсированный Microsoft Release Candidate, я сделал несколько быстрых заметок о значении пяти основных новинок, на которые следует обратить внимание!

1 - Ссылки на проект

Одно слово: МОНОРЕПО

«Монорепозиторий» - это единый репозиторий в выбранном диспетчере распределенной среды, который содержит несколько проектов с тесно связанными зависимостями API.

Это одна из самых важных составляющих, над которыми они работали в этом изменении, и, вероятно, одна из самых востребованных.

tsconfig

tsconfig.json получает 2 новых поля, позволяющих использовать этот новый API.

составной -

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

Предположим, у вас есть три проекта, пользовательский, контроллер и , и зависимости [x → (зависит от) y ] являются

на стороне пользователяконтроллер → модели

Если вы вносите изменения в модели, API-интерфейсы, основанные на ссылках проекта, можно использовать для обнаружения изменения в ядре, если типы (в контроллере файлы .d.ts), на которые они полагаются в моделях, изменились.

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

ссылки -

Ссылки, на которые уже много ссылок (тьфу) в составном объяснении, указывают другой путь tsconfig.json / предполагаемый каталог, содержащий его, который связывает проекты вместе. Это также сигнализирует TypeScript, что эти ссылочные зависимости должны быть построены в первую очередь.

режим сборки

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

Если вы используете микросервисы узлов, возможно, вы знакомы с gulp, который уже поддерживает эти интегрированные обновления конфигурации. Оркестраторы будущих сборок также будут ссылаться на эти конфигурации.

Новый флаг $ tsc - build позволяет простым приложениям и проектам отказаться от использования внешних инструментов! Также может использоваться в паре с другими флагами (- verbose, - dry, - clean, - force)

Сопоставление ввода с выводом

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

С новым изменением сейчас

  • общие проекты строятся независимо и
  • при импорте ../shared мы ищем файлы .d.ts в его выходном каталоге

Небольшое изменение, но убирает двойные сборки и поглощает ВСЕ содержимое.

Лучшая часть - никаких накладных расходов; Все это обрабатывается прежними изменениями jsconfig.

2 - Более плавная перегрузка функции

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

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

Так как же добиться краткости JavaScript при сохранении неизменности типов TypeScript?

Кортежи -

Эти сценарии теперь можно лучше смоделировать, разрешив общие параметры отдыха и определив эти универсальные типы как типы кортежей!

Вместо объявления каждой из этих перегрузок мы можем сказать, что параметр ...args rest из fn должен быть параметром типа, который расширяет массив, а затем мы можем повторно использовать его для ...args, который передает call:

Кроме того, в версии 3.0 использование кортежа в параметре rest сглаживается в остальной части списка параметров, сокращая его до простых параметров без кортежей:

Окончательное поведение

  • Ошибки типа будут обнаружены при передаче неправильных аргументов
  • Вывод типа из других аргументов
  • Наблюдайте за предполагаемыми типами кортежей при внешней проверке.

3 - Более богатые типы кортежей

Чтобы все это работало, пришлось расширять кортежи. Они должны были соответствовать 3 существующим ситуациям списка параметров -

Итак, кортежи соответствующим образом отреагировали на свой ввод:

1 - Параметры в конце могут быть необязательными

// 2D, or potentially 3D, coordinate.
type Coordinate = [number, number, number?];

Интересно, что, поскольку кортежи используют числовые буквальные типы для своих свойств length, свойство length Coordinate имеет тип 2 | 3.

2 - Последние параметры могут быть оставшимися параметрами

type LineNumberAndSomeStrings = [number, ...string[]];

Результирующее неограниченное поведение:

  • В приведенных выше примерах требуется число, а разрешает 0 или более строк.
  • Произвольное индексирование возвращает string | number , поскольку индекс будет неизвестен
  • Следовательно, свойство length равно number

Обратите внимание: когда нет других элементов, элемент rest в кортеже идентичен самому себе:

type Foo = [...number[]]; // Equivalent to `number[]`.

3 - Они могут быть пустыми

// referenced as [],length of 0, indexing returns never type
type EmptyTuple = [];

4 - Новый тип: неизвестно

Все программисты TypeScript в своих путешествиях по кодированию уступили соблазнительной легкости any type, особенно в среде тестирования.

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

Так почему мы его используем?

Очень часто мы хотим описать тип, наименее способный. Возьмем API, которые хотят сигнализировать, что «это может быть что угодно, поэтому вы должны выполнить какую-то проверку перед его использованием». any type обходит эти требования меры проверки, сохраняя при этом TypeScript счастливым и тихим.

войти неизвестно

Новый тип unknown выполняет именно эту проверку. Для подобных ситуаций множество вариаций и модификаций, которые побуждают пользователей безудержно работать с любыми типами, сдерживаются -

Каждый из вышеперечисленных any cases теперь будет выдавать ошибки, если вместо этого

let foo: unknown = 10;

Теперь мы вынуждены либо выполнить проверку, либо использовать утверждение типа, чтобы убедить систему типов в том, что мы знаем лучше:

let foo: unknown = 10;

function hasXYZ(obj: any): obj is { x: any, y: any, z: any } {
    return !!obj &&
        typeof obj === "object" &&
        "x" in obj &&
        "y" in obj &&
        "z" in obj;
}

// Using a user-defined type guard...
if (hasXYZ(foo)) {
    // ...we're allowed to access certain properties again.
    foo.x.prop;
    foo.y.prop;
    foo.z.prop;
}

// We can also just convince TypeScript we know what we're doing
// by using a type assertion.
upperCase(foo as string);

function upperCase(x: string) {
    return x.toUpperCase();
}

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

Разве это не будет здорово‽‽

Поддержка defaultProps в JSX

Инициализаторы по умолчанию - это автоматические чудеса, которые обеспечивают безопасность типов и делают код короче.

Внешне name является необязательным, и мы потенциально можем пропустить undefined или полностью его опустить.

React аналогичным образом использует defaultProps для заполнения любого пропущенного props.

Когда создается элемент Greet

const result = ReactDOM.renderToString(<Greet />);

name будет инициализирован с "world", и этот код будет печатать <div>Hello world!</div>.

Раньше TypeScript не понимал, что defaultProps имеет какое-либо отношение к вызовам JSX. Вместо этого пользователям часто приходилось объявлять свойства необязательными и использовать ненулевые утверждения (!) внутри render:

export interface Props { name?: string }
export class Greet extends React.Component<Props> {
    render() {
        const { name } = this.props;
        return <div>Hello ${name!.toUpperCase()}!</div>;
    }
    static defaultProps = { name: "world"}
}

LibraryManagedAttributes

В версии 3.0 TypeScript будет поддерживать новый псевдоним типа в пространстве имен JSX с именем LibraryManagedAttributes. Несмотря на длинное имя, это просто вспомогательный тип, который сообщает TypeScript, какие атрибуты принимает тег JSX.

tl; dr: используя этот общий тип, мы можем смоделировать конкретное поведение React для таких вещей, как defaultProps и, в некоторой степени, propTypes.

export interface Props {name: string}
export class Greet extends React.Component<Props> {
    render() {
        const { name } = this.props;
        return <div>Hello ${name.toUpperCase()}!</div>;
    }
    static defaultProps = { name: "world"}
}

// Type-checks! No type assertions needed!
let el = <Greet />

Вот и все 5 больших перерывов! В целом ожидается очень мало фактических перерывов в работе. С нетерпением жду этого!

✉️ Подпишитесь на рассылку еженедельно Email Blast от CodeBurst 🐦 Подпишитесь на CodeBurst на Twitter , просмотрите 🗺️ Дорожная карта веб-разработчиков на 2018 год и 🕸️ Изучите веб-разработку с полным стеком .