Комментарии 3
Для плюсовиков можете сразу напомнить разницу между темплейтами и дженериками: дженерик служит только для контроля типов, с any будет работать точно так же...
Позанудствую:
По-русски это называется «обобщенное программирование» и «обобщенные типы»
Им можно задавать значение по-умолчанию (через =), считается хорошей практикой «заземлять» все обобщенные типы на unknown, за исключением тривиальных типов, а то ts будет их радостно выводить в any при первой же возможности
«Как мы видим, если тип не передан в
<>
, то он выводится автоматически. Вывод типа делает код короче, но в сложных определениях может потребоваться явная передача типа.». TS не ленивый и КАКОЙ-ТО тип выведет всегда. Передавать нужно либо для сужения, либо для расширения типа (либо если в цепочке есть рак в виде any). Например:
const personArray = convertPersonToArray<Person>({ name: foo })
// personArray: [Person]
// без явного приведения будет
// personArray: [{ name: string }]
// но это совсем простой пример и так же радостно можно сделать обычное приведение типов
К слову, в таком тривиальном случае можно не указывать возврат функции тоже.
Классы:
В getFormattedData при наследовании можно и не указывать возвращаемый тип, покуда он определен в родителе
Стоит заметить, что у наследника могут быть свои обобщенные типы, но он должен указать все типы у родителя. Т.е.:
// работает
class ContactLocalDatabase<T> extends BaseLocalDataBase<ContactTable, T> {}
// уже нет
class ContactLocalDatabase extends BaseLocalDataBase<ContactTable> {} // not enough generic types
// заметьте, что если родитель имел бы второй тип со значением по-умолчанию, тогда бы сработало
Не стоит забывать о существовании перегрузки функций и об арифметических типах, часто они гораздо уместнее обобщенных типов.
Что такое дженерики в TypeScript?