Снова any. Заметка для новичка

от автора

Поводом для данной заметки стали несколько обстоятельств. Негативный опыт на одном проекте, и следующий спич в одном из докладов по ТС 2023 года:
«Так когда же использовать any? Никогда. Шучу, конечно. Если идет портирование или при разработке дженериков можно» — за точность уже отвечать не могу, но смысл примерно такой.
А так же заявления некоторых команд в духе: «У нас отличный проект. У нас нет any»

Так как относиться неискушенному разработчику к any?

Документация

Первым делом обратимся к современной документации на ТС. А имеем мы следующие:

TypeScript also has a special type, any, that you can use whenever you don’t want a particular value to cause typechecking errors.

И подобное действительно может ввести в заблуждение, что с any можно обращаться как с любым другим типом и использовать при разработке.
Потому что звучит это как: «У нас тут тип, что бы скрыть сообщения об ошибках типизации»

Пример 1.

export const anyAgainEx1 = () => {   const A: any = 1   const B: string = A    const C = B.repeat(10) } 

Запустив тест мы получим подтверждение, что функция выкинет исключение с ошибкой B.repeat is not a function

Таким образом, использовать any как тип в ТС проекте нельзя, потому что основная его функция — это отключать типизацию в месте использования.

И в документации об этом написано прямым текстом. Но не в самом разделе посвященном any, а в, на мой взгляд весьма отдаленном разделе, Do’s and Don’ts:

Don’t use any as a type unless you are in the process of migrating a JavaScript project to TypeScript. The compiler effectively treats any as “please turn off type checking for this thing”. It is similar to putting an @ts-ignore comment around every usage of the variable. This can be very helpful when you are first migrating a JavaScript project to TypeScript as you can set the type for stuff you haven’t migrated yet as any, but in a full TypeScript project you are disabling type checking for any parts of your program that use it.

И если мы не знаем какой тип должен быть на месте должны использовать unknown

Пример 2.

export const anyAgainEx2 = () => {   const A: unknown = 1   const B: string = typeof A === 'string' ? A : '1'    return B.repeat(2) } 

Generic

Когда у нас есть ТС проект any в нем все равно использовать можно.

Пример 3.

type A<T> = { value: T } type B<T> = T extends any ? A<T> : never type C<T extends { value: any }> = T extends { value: infer InnerT } ? InnerT : never  type testType = string | number  type Result = { value1: A<testType> // { value: string | number } value2: B<testType> // { value: string } | { value: number } value3: C<A<string> | B<number>> // string | number } 

Мы имеем два примера выразительного использования any

  • В первом случае таким образом ТС позволяет включать дистрибутивность объединения при передаче в дженерик

  • Во втором случае с помощью any мы определили форму ограничения для типа дженерика

Отключение типизации через any как рабочий вариант

Задача: Написать декоратор для функции, который подсчитывает количество вызовов

Пример 4.

export const anyAgainCounts: { [key: string]: number } = {}  const decoratorCount = function<T extends (...p: any) => any>(fn: T, desc: string): T {   anyAgainCounts[desc] = 0    return ((...params: any[]) => {     anyAgainCounts[desc]++      return fn(...params)   }) as T } 

Ключевые моменты использования any:

  1. Задание формы для типа параметра декорируемого подсчитывающей функцией

  2. Отключение типизации, т.к. в данном случае нас вообще не интересует с какими параметрами работает декорирующая функция. О количестве параметров должна заботится декорируемая функция.

Без any пример выглядит так:

const decoratorCount2 = <F extends (...args: Parameters<F>) => ReturnType<F>>(fn: F, desc: string) => {   anyAgainCounts[desc] = 0    return ((...params: Parameters<F>) => {     anyAgainCounts[desc]++      return fn(...params)   }) } 

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

Заключение

Так что же означает фраза: «У нас на проекте нет any»?

Во-первых, это говорит о стадии проекта. Либо он изначально был на ТС, либо все операции портирования завершены.

Во-вторых, any до сих пор может эффективно использоваться в TC проекте, но вот как тип его использование ограничено ясными продуманными ситуациями. Если же в проекте и в самом деле недолюбливают any просто так, то точно имеет смысл ознакомиться с особенностями из этой заметки.


ссылка на оригинал статьи https://habr.com/ru/articles/843116/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *