TypeScript 4.4: хороший, плохой, злой

0 0

Давайте разберемся, что нового, как это может повлиять на ваш опыт разработки и как попробовать его прямо сейчас!

Критические изменения

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

Вы больше не можете инициализировать abstract свойства внутри abstract классов. Вы можете только определить их тип.

Проверки рromise были улучшены.

TypeScript 4.4: хороший, плохой, злой

JavaScript. Быстрый старт

Изучите основы JavaScript на практическом примере по созданию веб-приложения

Значение по умолчанию параметров сatch теперь равно unknown вместо any, когда установлен любой флаг —strict или новый —useUnknownInCatchVariables.

Значение this игнорируется при вызове импортированных функций для согласования со спецификацией модулей ECMAScript во всех доступных модульных системах (ESM, AMD, CommonJS и т. д.)

Был изменен lib.d.ts, чтобы соответствовать текущим спецификациям (особенно lib.dom.d.ts со всеми изменениями, отмеченными здесь)

Разобравшись с этим, давайте посмотрим, какие новые функции вы можете ожидать!

Улучшенное обнаружение типа защиты

Вероятно, наиболее важной особенностью TypeScript 4.4 является «анализ потока управления условий сглаживания и дискриминантов».

Это означает, что с этого момента, псевдонимы типа защиты, будут должным образом анализироваться и использоваться для сужения данного типа. В предыдущих версиях TS следующее не работало.

JavaScript const example = (arg: string | number) => { const isString = typeof arg === “string”; if (isString) { return arg.toUpperCase(); // Error } return arg.toPrecision(); // Error };

123456789const example = (arg: string | number) => {  const isString = typeof arg === “string”;   if (isString) {    return arg.toUpperCase(); // Error  }   return arg.toPrecision(); // Error};

Значение isString не позволяло TS узнать, что, когда оно true, то arg является String. В результате TS выдавал ошибку, когда вы использовали методы и свойства, зависящие от типа, но при этом думали, что arg имеет тип string или number. Правильно интерпретировалось только помещение условия в оператор if.

Благодаря улучшенному анализу потока управления это больше не будет проблемой в TS 4.4. Кроме того, TS также обнаруживает правильные типы при работе с дискриминантными объединениями.

JavaScript type Shape = | { kind: “circle”; radius: number } | { kind: “square”; sideLength: number }; const area = (shape: Shape): number => { const { kind } = shape; const isCircle = kind === “circle”; // shape.kind === “circle” will also work if (isCircle) { // Circle return Math.PI * shape.radius ** 2; } // Square return shape.sideLength ** 2; };

123456789101112131415type Shape =  | { kind: “circle”; radius: number }  | { kind: “square”; sideLength: number }; const area = (shape: Shape): number => {  const { kind } = shape;  const isCircle = kind === “circle”; // shape.kind === “circle” will also work   if (isCircle) {    // Circle    return Math.PI * shape.radius ** 2;  }  // Square  return shape.sideLength ** 2;};

До определенной глубины TS также распознает более сложные комбинированные условия и соответственно сузит тип.

JavaScript const example = (x: string | number | boolean) => { const isString = typeof x === “string”; const isNumber = typeof x === “number”; const isStringOrNumber = isString || isNumber; if (isStringOrNumber) { x; // string | number } else { x; // boolean. } };

1234567891011const example = (x: string | number | boolean) => {  const isString = typeof x === “string”;  const isNumber = typeof x === “number”;  const isStringOrNumber = isString || isNumber;   if (isStringOrNumber) {    x; // string | number  } else {    x; // boolean.  }};

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

Более универсальные сигнатуры индекса

Еще одно важное улучшение связано с индексными сигнатурами. Вы больше не будете ограничены только number и string. Теперь symbol и шаблоны строк шаблона также будут разрешены.

JavaScript interface Colors { [sym: symbol]: number; } const red = Symbol(“red”); const green = Symbol(“green”); const blue = Symbol(“blue”); const colors: Colors = {}; colors[red] = 255; colors[red]; // number colors[blue] = “da ba dee”; // Error colors[“blue”]; // Error

12345678910111213interface Colors {  [sym: symbol]: number;} const red = Symbol(“red”);const green = Symbol(“green”);const blue = Symbol(“blue”);const colors: Colors = {}; colors[red] = 255;colors[red]; // numbercolors[blue] = “da ba dee”; // Errorcolors[“blue”]; // Error

Индексные сигнатуры symbol — хорошее дополнение. Однако, на мой взгляд, сигнатуры индекса шаблона строки гораздо интереснее! Это позволит вам сузить подпись индекса до определенного шаблона, позволяя определять сложные типы, как никогда раньше!

JavaScript interface Example { a: number; b: string; [prop: `data-${string}`]: string; } const test1: Example = { a: 1, b: “example”, “data-test”: “example”, }; const test2: Example = { “data-test”: “example”, }; // Error (no “a” and “b”) const test3: Example = { a: 1, b: “example”, test: “example”, }; // Error (“test” not accepted)

12345678910111213141516171819interface Example {  a: number;  b: string;  [prop: `data-${string}`]: string;} const test1: Example = {  a: 1,  b: “example”,  “data-test”: “example”,};const test2: Example = {  “data-test”: “example”,}; // Error (no “a” and “b”)const test3: Example = {  a: 1,  b: “example”,  test: “example”,}; // Error (“test” not accepted)

Если вы когда-нибудь хотели использовать сигнатуры индекса, но сузить ее до общего string, это обновление будет для вас огромным подарком!

Кроме того, также будут разрешены объединения индексных сигнатур. Любая комбинация string, number, symbol, и шаблон строки является приемлемой.

JavaScript interface Example { [prop: string | number]: string; }

123interface Example {  [prop: string | number]: string;}

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

Кроме флага —useUnknownInCatchVariables, введен еще один —exactOptionalPropertyTypes. Если этот флаг включен, TS больше не позволяет инициализировать дополнительные свойства с помощью undefined.

JavaScript interface Example { a: string; b?: number; } const test: Example = { a: “example”, b: undefined, // Error if –exactOptionalPropertyTypes is turned on };

123456789interface Example {  a: string;  b?: number;} const test: Example = {  a: “example”,  b: undefined, // Error if –exactOptionalPropertyTypes is turned on};

Такое поведение, определяющее, действительно ли свойство присутствует в объекте, полезно в нескольких случаях. При использовании, например, Object.assign или object spread ( { …obj }), свойства с undefined фактически обрабатываются иначе по сравнению с действительно несуществующими свойствами. В зависимости от реализации то же самое может быть верно и для вашего кода.

Чтобы разрешить undefined с включенным —exactOptionalPropertyTypes, вам нужно будет явно включить undefined в тип объединения. Без флага такое поведение происходит автоматически.

TypeScript 4.4: хороший, плохой, злой

Фреймворк VUE JS: быстрый старт, первые результаты

Получите бесплатный курс и узнайте, как создать веб-приложение на трендовой Frontend-технологии VUE JS с полного нуля

JavaScript interface Example { a: string; b?: number | undefined; } const test: Example = { a: “example”, b: undefined, // Works correctly (even with –exactOptionalPropertyTypes on) };

123456789interface Example {  a: string;  b?: number | undefined;} const test: Example = {  a: “example”,  b: undefined, // Works correctly (even with –exactOptionalPropertyTypes on)};

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

Если вы чувствуете, что это может помочь в вашей кодовой базе, включите этот флаг вместе с —strictNullChecks.

Статические блоки в классах

Последняя большая новая функция – static блоки. Это предстоящая функция ECMAScript. Static блоки позволяют инициализировать статические члены класса.

JavaScript class Example { static count = 0; // Static block static { if (someCondition()) { Example.count++; } } }

12345678910class Example {    static count = 0;     // Static block    static {        if (someCondition()) {            Example.count++;        }    }}

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

JavaScript class Example { static count = 0; } if (someCondition()) { Example.count++; }

1234567class Example {  static count = 0;} if (someCondition()) {  Example.count++;}

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

JavaScript let exampleFunc!: (instance: Example) => number; class Example { static #accessCount = 0; #initial: number; constructor(input: number) { this.#initial = input * 2; } static { exampleFunc = (instance: Example) => { Example.#accessCount++; return instance.#initial } } } if (exampleFunc) { exampleFunc(new Example(2)); // 4 }

123456789101112131415161718192021let exampleFunc!: (instance: Example) => number; class Example {  static #accessCount = 0;  #initial: number;  constructor(input: number) {    this.#initial = input * 2;  }   static {    exampleFunc = (instance: Example) => {      Example.#accessCount++;       return instance.#initial    }  }} if (exampleFunc) {  exampleFunc(new Example(2)); // 4}

Улучшения производительности

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

Более быстрая передача деклараций благодаря дополнительному кэшированию.

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

Более быстрое сопоставление путей для tsconfig.json, благодаря дополнительному кэшированию, приводит к значительному повышению производительности.

Более быстрая инкрементная сборка —strict благодаря исправлению ошибки, вызывающей ненужную проверку типов при каждой последующей сборке.

Более быстрое создание исходной карты для результатов большого объема

Более быстрые сборки —force благодаря сокращению ненужных проверок

Улучшения Intellisense

Область, в которой TS наиболее известна — intellisense (также известная как поддержка автозаполнения / редактора), также претерпела некоторые улучшения.

По мере того, как предложения TS становятся более самодостаточными, начиная с версии 4.4, они будет автоматически выдавать варианты правописания для файлов на чистом JavaScript без включения checkJs или @ts-check.

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

TypeScript 4.4: хороший, плохой, злой

Также улучшены предлагаемые пути импорта. Вместо относительных путей, таких как node_modules/… в TS, будут отображаться пути, которые вы действительно используете — вроде react вместо node_modules/react/.. или что-то в этом роде. Косметическое, но приветствуемое изменение.

TypeScript 4.4: хороший, плохой, злой

Тест-драйв

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

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

JavaScript npm install typescript@rc

1npm install typescript@rc

Затем, при необходимости, выберите его для использования в вашем редакторе IDE / кода. Естественно, VS Code обеспечит вам лучший опыт, а с VS Code Insiders вы получите последнюю версию TS прямо из коробки.

Заключение

Итак, вот оно что! В TS 4.4 появятся тонны улучшений, а запланировано еще больше. Если вы пользователь TS, это будет для вас хорошим обновлением. Это наверняка улучшит ваш опыт разработки. И если вы еще не используете TS, может быть, вам пора попробовать?

Автор: Arek Nawo

Источник: webformyself.com

Оставьте ответ