6:45 это очень спорное утверждение в отношении того, когда и что использовать. Интерфейсы и типы во многом взаимозаменяемы. Как следует из двух важных отличий интерфейсов от типов, а именно: не возможность расширить интерфес от union-типа, и невозможность расширить декларацию типа, то интерфейс надо использовать, когда потребуется по-разному расширять его декларацию (например, на бэке и на фронте setTimeout имеет разныую сигнатуру), а типы надо использовать, когда требуется создание union типов. Конечно, нужно учесть, что интерфейсы являются более привычными для сторонников классического (JAVA-подобного) ООП, и собственно, невозможность наследования от union типа обусловленна именно этим фактом. У нас на проектах: типы -- для анимичных моделей, интерфейсы -- для описания поведения. Фактически получается, что все доменные объекты описаны типами, а все сервисы описаны интерфейсами. у объектов нет методов, есть только поля, а у сервисов нет полей, только -- методы. Но, это все не более, чем соглашение одной команды для определенной группы проектов. В подавляющем большинстве случаев стоит выбрать тот инструмент, который более удобен (привычен) для вашей команды.
Когда пользуешься типами на уровне A: string,, B: number, то от скуки возникает странное желение начинать спорить где и что лучше использовать... Когда пишешь свои универсальные типы на дженериках, то такой вопрос не стоит)
@@Mr.Bellamy ну, якщо сперичатися про програмування, то від нудьги, то сперичатися про сперічання, то, мабудь, від дуже великої нудьги ;) Я, наприелад, цілеом погоджуюся з Вашим висловом: "Говорю, как использую сам. Это не значит, что все должны писать так же". Шкода, що цього уточнення не має у відео, і шкода, що я з легкістю можу отримати посилання на це відео, як аргумент на використання синтаксісу інтерфейса для анемічної моделі. От і все.
мне кажется там все предельно понятно, если ты понимаешь концепцию интерфейса. а type им следовало назвать alias и тогда бы точно не было бы никаких путаниц
Пардон, но я что-то не догнал вашего утверждения о том что длинна кортежа не меняется,. Почему тогда основываясь на вашем примере могу пушить данные в переменную с типом State и длинна массива меняется?
Кортеж нельзя опиcать интерфейсом. В этой реализации можно деструктеризировать любое количество ствойств, и все они будут any. Что значит вы типизировали не кортеж, а 2 первых элемента массива. const [value, effect, a, b, c] = state; TypeScript не будет ругаться на такую запись.
@@wisejs Да, строго говоря, это действительно не кортеж. Это массив с по-разному типизированными элементами. И да, если так наследоваться, то лучше от Array. Немного безопаснее.
3:40 NamesA и NamesB разные декларации. NamesB является аналогом вот такой: type NameC = { [idx: number]: string } У обоих деклараций, и NamesB и NamesC будут отсуствовать методы массива. const b: NamesB = ['a', 'b', 'c']; b.length -- выдасть ошибку "length" is not present in NamesB Аналогом NamesA будет: interface NamesD extends Array {};
@@wisejs NamesC тоже тип. И опять же, смотря что надо описать. Может так и надо сделать, чтобы не было методов массива и читать надо было по прямому индексу. Кстати, как параметр функции вполне подойдет
Было бы интересно про перегрузку послушать тк на практике не приходилось использовать, соответственно полного понимания непосредственно, зачем реализована такая возможность нет. Буду благодарен за пример из жизни, а не на "котиках")))
вы вроде не сказали в ролике главного отличия, как написано в документации, что type cannot be re-opened to add new properties vs an interface which is always extendable
2:02 надо еще SumC добавить. Аналог SumA. type SumС = { (a: number, b: number): number; } const sum: SumC = (a, b) => a + b; Здесь надо сказать, что SumA и SumC нужны когда для функии задаются дополнительные свойства (как, например, в случае с express), в остальных случаях функцию лучше тайпать, как SumB -- проще читается.
В видео очень много ошибок и неточностей 3:42 NameA и NameB не идентичные типы, тут записть NameA эквивалентна типу Array, в то время как NameB это Record. Первое - массив строк, второе - объект с ключами типа number и значениями типа string, во втором случае отсутствуют поля и методы массива как length, push, pop и так далее 5:16 const obj: C = .... в этом случае поля age и name разрешены не потому что тип C объявлен как A | B, а потому что из-за структурной типизиции к объекту типа C можно добавить любое поле и он все еще будет иметь тип C. Сам тип A | B описывает либо поле name, либо age, но не два сразу. Для этог онужно использовать запись A & B
Как динамически менять дженерик тип. Есть функция которая отрабатывает и получает DataCode от 1 - 11 . Нужно как то организова такой функционал. type AllKey = "A" | "B" | "C".... I_Test interface I_Test { name: string; item: Array ; }
@@wisejs Как в разный момент времени подкидывать в let a:I_Test = {name: "Вася", items: [{model: "BMW"}] let a:I_Test = {name: "Петя", items: [{cityl: "Moscow"}] let a:I_Test = {name: "Борис", items: [{prof: "Повар-тракторист"}] и т. д. В функции в которой переменная "a" меняеться приходит так же при разном вызове одно из чисел от 1-11. типов так же от 1-11 существует мне как то надо их подкидывать ориентируясь на число
Вопрос по теме union, есть ли в ts возможность описать, например тип С, так, чтобы он принимал либо только свойство из типа А, либо только свойство из типа В?
Вроде как в самом ts нет встроенного утильного типа, но в целом это называется mutually exclusive types или XOR, на стэковерфлоу есть реализация, гугл выдаёт первой ссылкой
У меня как то был косяк с аргументами функции При такой записи: const getTableRows = (someArg: ISomeArg[], columns: ITypeA[] | ITypeB[]) => .... тайп скрипт ругался на: This expression is not callable. Я заменил это на const getTableRows = (someArg: ISomeArg[], columns: C[]) => .... и лыжи поехали. Это какой то Юнион тайп из мира интерфейса получился что ли? P.S В итоге всё равно пришлось переделать , а то выглядело не оч))
Можно было написать проще, с тем же результатом: `const getTableRows = (someArg: ISomeArg[], columns: (ITypeA | ITypeB)[]) => ...` С т.з. типобезопасности, `Array | Array` - это не то же самое, что `Array`. Но вот то, что переменная с типом `const arr: Array | Array` создаёт больше проблем, чем пользы - это реально вымораживает, даже если ITypeA и ITypeB структурно идентичны. В итоге приходится идти на компромисс (это ж ts, как тут без компромиссов) и менять тип на `const arr: Array` и тогда "лыжи начинают ехать"
Спасибо за видео. А нету у Вас случайно в планах записать видео по правильному подключению роутов, если есть как публичные роуты так и приватные. В интернете есть разная информация: кто-то создает 2 объекта: publicRoutes и privateRoutes, в другом способе объект единый, но компонент делают свой - кастомный роут - privateRoute. И как правильно построить структуру, если например есть не только user и admin, а, допустим 3 уровня доступа, user; moderator; admin; Про то, как правильно организовать все в таком случае информации вообще нету. Спасибо
@@denisdragomirik golang или любой строго типизированный язык программирования тебе в помощь, чтобы разобраться в разнице между типом и интерфейсом. Даже всеми ненавидимый php с динамической типизацией знает что есть тип, а что есть интерфейс, и только нубы от тайпскрипта никак её не поймут.
@@kdnlinker а ти уяви, що в тебе не властивість, а геттер. А геттер - це метод. Якщо не згоден - вчи основи TypeScript. У C#, до речі, подібна концепція
@@denisdragomirik ghbx`v pltcm ctnnth b utnnth? ns rjulf yf [j[kzwrjv dtoftim? nj dtofq d cdjtq [j[kj;jgbb/ Включишь русскую раскладку и прочитаешь, а как у Зели спросишь.
Автор видео не понял смыслового различия между Interface и Type. В офф документации TypeScript, других С-подобных языках и книгах по ОПП есть чёткое описание предназначения. Для тех кто хочет это действительно понять, обратитесь к этой литературе.
За что же JavaScript`у так не повезло?! TypeScript это - самая уродливая разработка которую я видел за 33 года работы программистом. Создавая его авторы не имели конкретной цели - внесли кучу путаницы, так и не делегировав относительность и приоритеты типов и интерфейсов. По всей видимости и сейчас не могут. Что мешало сделать интерпретатор с (например) Java или C# через WebAssembly - в JavaScript? Как я люблю Web разработку и как я устал от постоянной костылизации решений. Создание интерпретатора - не тривиальная задача! Но ...чего не хватает в мире JavaScript разработки так это - архитекторов!
@@konstantinov_it Я думаю может просто не нужно его воспринимать так серьезно - как язык программирования. Он как был - script, так и остался - скриптом. В этом его прелесть. Да и javascript - не панацея, а одно из решений для web задач. Можно писать Web не только на JavaScript`е. Просто что последнее - менее популярное решение.
@@ugin-nb4syХах, ты какие-то курсы проходил? "Как поверить в себя за 15 дней" ? Малыш )) Откуда ты такой мотивированный? ))) Видно что ты еще - зеленый как трава ))) Твои розовые рассуждения выдают твой возраст, сын )
@@ugin-nb4syА шо ты такое вообще? AI который поверил в себя? Сын, мне вообще твое мнение - ...по барабану (мягко сказано). Мои скилы еще какой-то "июнь" не проверял 😀 Я плачу от такого расклада ))) Ты мне начинаешь нравится - ты смешной! 😀Может к тебе еще на курсы записаться? 😀😀😀😀😀
офигительная лекция. Просто супер. Процветания тебе, Автор!
6:45 это очень спорное утверждение в отношении того, когда и что использовать. Интерфейсы и типы во многом взаимозаменяемы. Как следует из двух важных отличий интерфейсов от типов, а именно: не возможность расширить интерфес от union-типа, и невозможность расширить декларацию типа, то интерфейс надо использовать, когда потребуется по-разному расширять его декларацию (например, на бэке и на фронте setTimeout имеет разныую сигнатуру), а типы надо использовать, когда требуется создание union типов.
Конечно, нужно учесть, что интерфейсы являются более привычными для сторонников классического (JAVA-подобного) ООП, и собственно, невозможность наследования от union типа обусловленна именно этим фактом.
У нас на проектах: типы -- для анимичных моделей, интерфейсы -- для описания поведения. Фактически получается, что все доменные объекты описаны типами, а все сервисы описаны интерфейсами. у объектов нет методов, есть только поля, а у сервисов нет полей, только -- методы. Но, это все не более, чем соглашение одной команды для определенной группы проектов.
В подавляющем большинстве случаев стоит выбрать тот инструмент, который более удобен (привычен) для вашей команды.
Говорю, как использую сам. Это не значит что все должны писать так же.
Мы тоже в команде придерживаемся подобного подхода.
Когда пользуешься типами на уровне A: string,, B: number, то от скуки возникает странное желение начинать спорить где и что лучше использовать...
Когда пишешь свои универсальные типы на дженериках, то такой вопрос не стоит)
@@Mr.Bellamy ну, якщо сперичатися про програмування, то від нудьги, то сперичатися про сперічання, то, мабудь, від дуже великої нудьги ;)
Я, наприелад, цілеом погоджуюся з Вашим висловом:
"Говорю, как использую сам. Это не значит, что все должны писать так же".
Шкода, що цього уточнення не має у відео, і шкода, що я з легкістю можу отримати посилання на це відео, як аргумент на використання синтаксісу інтерфейса для анемічної моделі.
От і все.
Когда смотрю такие видео - понимаю, как мало я знаю... Спасибо за видео
Какие темы по TypeScript раскрывать в следующих видео?
Generic и когда их стоит использовать.
Mixins, особенно как юзать в ангуляре
Женерики
Прям ваще годное видео - чётко, сжато, конкретно и по делу! Однозначно Like 👍
Респект за сохраненное время!
Круто объяснил! Спасибо огромное, все понятно, крутые примеры!
Хорошее видео! Четко и без воды
0:25 для этих целей так же можно использовать и class и typeof любього объекта (но это считай будет type, только без присвоенного типа)
Спасибо что продолжаете радовать нас отличным контентом!
Спасибо друг за твою работу...
мне кажется там все предельно понятно, если ты понимаешь концепцию интерфейса.
а type им следовало назвать alias и тогда бы точно не было бы никаких путаниц
Полезно, спасибо
Спасибо! Много новых тонкостей узнал.
Очень доходчиво объяснил про разницу Type и Interface в Typescript
Спасибо за ключевые слова))
Урок очень хороший много понятно стало
спасибо, кратко, толково, без воды. случайно попал сюда, подписался
спасибо, сюда попали все случайно, но остаются не случайно😉
Гооодно!!! 🙏🏻💪🏻
Хороший урок. Но по поводу последнего, то это субъективно. Так как это уже больше принимается на уровне команды и по сути отличий у них почти нет
Согласен. Это правило, которое использую я.
Привет всем, не могли бы подсказать, какой тип 'file' будет в реакте?
Хорошее видео, спасибо!
Пардон, но я что-то не догнал вашего утверждения о том что длинна кортежа не меняется,. Почему тогда основываясь на вашем примере могу пушить данные в переменную с типом State и длинна массива меняется?
у меня в редакс тулките store ругается на этот интерфейс, переименовал в type и теперь норм. Не пойму в чем дело
Все четко и по делу!👍🏻👍🏻👍🏻
Спасибо, очень полезно!
Очень хороший урок. Большой молодец👍, ждем продолжения
TypeScript и Saga
Спасибо! хороший урок!
Огонь, спасибо, больше ТС в ньюансах!
Красвава!
Покажите как типизировать API и функции высшего порядка. Годного материала не могу найти. Спасибо.
риал
дженерики в помощь
Он значительно лучше express и если вам нужна типизация, а для разработки хороших АПИ, она вам нужна, то это идеальный вариант
Хороший урок.
Есть еще интересная тема - типы событий. Где и какие типы указывать, неясно.
Еще интересная тема - ответ от сервера. Какие типы указать
Спс за годный контент, а то я в ts недавно, многих вещей ещё не знаю
Хороший урок, спасибо за труд!
3:47
Вторая запись не предлагает наличие методов массива в экземпляре
Отличное описание нюансов, краткое и ёмкое, спасибо
Спасибо за комментарий!
Интересно!
Хотелось бы хорошо разобраться с декораторами.
Красавчик!
3:52 - Кортеж можно описать интерфейсом. Правда, это будет выглядеть несколько громоздко и непривычно, но это возможно:
interface IState extends Array {
[0]: number;
[1]: (n: number) => void;
length: 2;
}
const state: IState = [10, (n) => console.log(10 + n)];
const [value, effect] = state;
Кортеж нельзя опиcать интерфейсом.
В этой реализации можно деструктеризировать любое количество ствойств, и все они будут any. Что значит вы типизировали не кортеж, а 2 первых элемента массива.
const [value, effect, a, b, c] = state;
TypeScript не будет ругаться на такую запись.
@@wisejs
Да, строго говоря, это действительно не кортеж.
Это массив с по-разному типизированными элементами.
И да, если так наследоваться, то лучше от Array.
Немного безопаснее.
Круто!
3:40 NamesA и NamesB разные декларации. NamesB является аналогом вот такой:
type NameC = { [idx: number]: string }
У обоих деклараций, и NamesB и NamesC будут отсуствовать методы массива.
const b: NamesB = ['a', 'b', 'c'];
b.length -- выдасть ошибку "length" is not present in NamesB
Аналогом NamesA будет:
interface NamesD extends Array {};
Тут нужно отдавать приоритет типам.
@@wisejs NamesC тоже тип.
И опять же, смотря что надо описать.
Может так и надо сделать, чтобы не было методов массива и читать надо было по прямому индексу.
Кстати, как параметр функции вполне подойдет
Хорошо осветил
Было бы интересно про перегрузку послушать тк на практике не приходилось использовать, соответственно полного понимания непосредственно, зачем реализована такая возможность нет. Буду благодарен за пример из жизни, а не на "котиках")))
Сделаю про перегрузку.
@@wisejs спасибо, жду с не терпением
Привет всем, не могли бы подсказать, какой тип 'file' будет в реакте?
вы вроде не сказали в ролике главного отличия, как написано в документации, что type cannot be re-opened to add new properties vs an interface which is always extendable
разве этого не звучало может не дословно, но по смыслу так?
6:02
2:02 надо еще SumC добавить. Аналог SumA.
type SumС = {
(a: number, b: number): number;
}
const sum: SumC = (a, b) => a + b;
Здесь надо сказать, что SumA и SumC нужны когда для функии задаются дополнительные свойства (как, например, в случае с express), в остальных случаях функцию лучше тайпать, как SumB -- проще читается.
Да, верно. Второй ваш коммент RUclips забанил, не могу его прочесть и ответить.
о каких дополнительных свойствах идет речь? SumA.propertie = 123 ?
разобрался, верно
Красава!
Это получается все что связано с Mapped types и Utility types лучше использовать в type?
лучше всего да, ибо через интерфейсы это как бы не получится)
В видео очень много ошибок и неточностей
3:42
NameA и NameB не идентичные типы, тут записть NameA эквивалентна типу Array, в то время как NameB это Record. Первое - массив строк, второе - объект с ключами типа number и значениями типа string, во втором случае отсутствуют поля и методы массива как length, push, pop и так далее
5:16
const obj: C = .... в этом случае поля age и name разрешены не потому что тип C объявлен как A | B, а потому что из-за структурной типизиции к объекту типа C можно добавить любое поле и он все еще будет иметь тип C. Сам тип A | B описывает либо поле name, либо age, но не два сразу. Для этог онужно использовать запись A & B
именно так и подумал когда смотрел видео. хорошо что Вы это выразили текстом.
Как динамически менять дженерик тип. Есть функция которая отрабатывает и получает DataCode от 1 - 11 . Нужно как то организова такой функционал. type AllKey = "A" | "B" | "C".... I_Test interface I_Test { name: string; item: Array ; }
Ничего не понял.
@@wisejs Как в разный момент времени подкидывать в let a:I_Test = {name: "Вася", items: [{model: "BMW"}] let a:I_Test = {name: "Петя", items: [{cityl: "Moscow"}] let a:I_Test = {name: "Борис", items: [{prof: "Повар-тракторист"}] и т. д. В функции в которой переменная "a" меняеться приходит так же при разном вызове одно из чисел от 1-11. типов так же от 1-11 существует мне как то надо их подкидывать ориентируясь на число
Можете пример кода прикрепить с ошибкой?
Вопрос по теме union, есть ли в ts возможность описать, например тип С, так, чтобы он принимал либо только свойство из типа А, либо только свойство из типа В?
Вроде как в самом ts нет встроенного утильного типа, но в целом это называется mutually exclusive types или XOR, на стэковерфлоу есть реализация, гугл выдаёт первой ссылкой
Возможно Record
type xor = keyof A | keyof B;
А скажи плиз свое мнение насчет типизации пропсов
Type vs Interface
Я юзаю просто React.FC
@@wisejs а если кол-во пропсов 10+
Чаще всего это значит что компонент делает слишком много всего, и нужно изменить апи)
У меня как то был косяк с аргументами функции
При такой записи:
const getTableRows = (someArg: ISomeArg[], columns: ITypeA[] | ITypeB[]) => ....
тайп скрипт ругался на: This expression is not callable.
Я заменил это на
const getTableRows = (someArg: ISomeArg[], columns: C[]) => ....
и лыжи поехали.
Это какой то Юнион тайп из мира интерфейса получился что ли?
P.S В итоге всё равно пришлось переделать , а то выглядело не оч))
А причем здесь интерфейс? Extends тут выполняет совсем другую роль. Он ограничивает тип, а не расширяет его.
Можно было написать проще, с тем же результатом:
`const getTableRows = (someArg: ISomeArg[], columns: (ITypeA | ITypeB)[]) => ...`
С т.з. типобезопасности, `Array | Array` - это не то же самое, что `Array`.
Но вот то, что переменная с типом `const arr: Array | Array` создаёт больше проблем, чем пользы - это реально вымораживает, даже если ITypeA и ITypeB структурно идентичны. В итоге приходится идти на компромисс (это ж ts, как тут без компромиссов) и менять тип на `const arr: Array` и тогда "лыжи начинают ехать"
Все классно, но очень быстро, мало примеров
по-моему, достаточно)
Спасибо за видео. А нету у Вас случайно в планах записать видео по правильному подключению роутов, если есть как публичные роуты так и приватные. В интернете есть разная информация: кто-то создает 2 объекта: publicRoutes и privateRoutes, в другом способе объект единый, но компонент делают свой - кастомный роут - privateRoute. И как правильно построить структуру, если например есть не только user и admin, а, допустим 3 уровня доступа, user; moderator; admin; Про то, как правильно организовать все в таком случае информации вообще нету. Спасибо
Хорошая идея, запишу себе 😉
не удаляй пока видос. я попозже посмотрю что ты там сделал.
Не планировал ))
расскажи про дженерики плз
Интерфейс должен определять методы, но никак не свойства, тогда сразу будет понимание разницы между типом и интерфейсом.
Удачи 😁
@@denisdragomirik golang или любой строго типизированный язык программирования тебе в помощь, чтобы разобраться в разнице между типом и интерфейсом. Даже всеми ненавидимый php с динамической типизацией знает что есть тип, а что есть интерфейс, и только нубы от тайпскрипта никак её не поймут.
@@kdnlinker а ти уяви, що в тебе не властивість, а геттер. А геттер - це метод. Якщо не згоден - вчи основи TypeScript. У C#, до речі, подібна концепція
@@denisdragomirik ghbx`v pltcm ctnnth b utnnth? ns rjulf yf [j[kzwrjv dtoftim? nj dtofq d cdjtq [j[kj;jgbb/ Включишь русскую раскладку и прочитаешь, а как у Зели спросишь.
@@kdnlinker Не збираюсь)
Интерфейс не попадает в компиляцию
Тип тоже. Тайпскрипт типы вообще не попадают в компиляцию.
Автор видео не понял смыслового различия между Interface и Type. В офф документации TypeScript, других С-подобных языках и книгах по ОПП есть чёткое описание предназначения. Для тех кто хочет это действительно понять, обратитесь к этой литературе.
в 2 словах? куда копать?
с учетом особенностей попробоавали везде использовать интерфейсы и только когда этого совсем нельзя, то типы и все нормально получается.
сайдет подписочка
Ещё нельзя наследовать классы от типов, только интерфейсы
Классы и от интерфейсов нельзя наследовать. Класс - это реализация интерфейса. A extends в интерфейсе работает с типом, что я и показываю в видео.
👉 Этот комментарий создан в качестве уважения автору и для продвижения его канала.
ответил с той же целью длинною более 4 слов, поскольку присутствует полезное содержимое.
@@romanmed9035 ну и я тогда поддержу, можно ещё политический срач развести, тогда комментариям не будет отбоя:)
@@user-Duke2017 ну срач наверное все же не надо. остановимся на приличном.
За что же JavaScript`у так не повезло?! TypeScript это - самая уродливая разработка которую я видел за 33 года работы программистом. Создавая его авторы не имели конкретной цели - внесли кучу путаницы, так и не делегировав относительность и приоритеты типов и интерфейсов. По всей видимости и сейчас не могут. Что мешало сделать интерпретатор с (например) Java или C# через WebAssembly - в JavaScript? Как я люблю Web разработку и как я устал от постоянной костылизации решений. Создание интерпретатора - не тривиальная задача! Но ...чего не хватает в мире JavaScript разработки так это - архитекторов!
Умом JS нам не понять,
Аршином общим не измерить:
У ней особенная стать -
В JS мы можем только верить.
@@konstantinov_it Я думаю может просто не нужно его воспринимать так серьезно - как язык программирования. Он как был - script, так и остался - скриптом. В этом его прелесть. Да и javascript - не панацея, а одно из решений для web задач. Можно писать Web не только на JavaScript`е. Просто что последнее - менее популярное решение.
@@ugin-nb4sy Через лет 5 Vaadin и TS будет чем-то вроде jQuery или Adobe Flash - что с этим делать? Ты будешь сопровождать это барахло? )))
@@ugin-nb4syХах, ты какие-то курсы проходил? "Как поверить в себя за 15 дней" ? Малыш )) Откуда ты такой мотивированный? ))) Видно что ты еще - зеленый как трава ))) Твои розовые рассуждения выдают твой возраст, сын )
@@ugin-nb4syА шо ты такое вообще? AI который поверил в себя? Сын, мне вообще твое мнение - ...по барабану (мягко сказано). Мои скилы еще какой-то "июнь" не проверял 😀 Я плачу от такого расклада ))) Ты мне начинаешь нравится - ты смешной! 😀Может к тебе еще на курсы записаться? 😀😀😀😀😀
Урок сложный. Новичку непонятно
Сложно
ruclips.net/video/hGdx0hpZsvs/видео.html interface D {
name?:string;
age?:number;} интерфей так может