Code Monkey home page Code Monkey logo

exercises-typescript's Introduction

exercises-typescript

Github Actions Status

How to contribute

Requirements

  • docker
  • docker compose V2
  • make

Develop

# setup
make
# run
make compose
# check
make ci-check

# run tests
make compose-test

# run linters and validators
make code-lint
make compose-description-lint
make compose-schema-validate

Hexlet Ltd. logo

This repository is created and maintained by the team and the community of Hexlet, an educational project. Read more about Hexlet.

See most active contributors on hexlet-friends.

exercises-typescript's People

Contributors

alex-luov avatar amd-9 avatar ashikov avatar bondiano avatar corsicanec82 avatar dzencot avatar emp7yhead avatar evgeniyworkbel avatar fey avatar georgy-p avatar guryanov-maksim avatar helenone avatar kuramaa922 avatar malcom1986 avatar misterdrog avatar mokevnin avatar movmovbaby avatar novvember avatar ola-9 avatar reznikovandrey avatar sgmdlt avatar someden avatar sseezov avatar ssssank avatar teratron-git avatar txmrv avatar tysky avatar v1valasvegan avatar viktorkasap avatar vladikkir avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

exercises-typescript's Issues

Используется тема, которая изучается в следующем уроке

Тема: Анонимные функции
В решении задачи используется тип массива, но объясняется про типы массивов только в следующем уроке

Решение учителя:

const numbers = [1, 3, 8, 9, 100, 23, 55, 34];

// BEGIN
function getEvenNumbers(): number[] {
  const evenNumbers = numbers.filter((n) => n % 2 === 0);

  return evenNumbers;
}
// END

export default getEvenNumbers;

Опечатка урок 31

В тексте:
Здесь 2 используется как литеральный тип, который представляет из себя множество из одного элемента – единицы.

Надо:
Здесь 2 используется как литеральный тип, который представляет из себя множество из одного элемента – двойки.

Заменить maxFileSize на maxCustomFileSize в примерах к 39 уроку

В 39 уроке про статические св-ва и методы в примерах допущена ошибка:
употребляется maxFileSize и maxCustomFileSize одновременно, хотя по факту используется одно и то же

Чтобы проверить, что ошибка действитедьно присутствует, можно перенести код в ts песочницу и глянуть на ошибки

Ошибка в решении учителя "Объектные типы (Object Types)" 7/55

Определение параметров записано неверно:
function isComplete(course: { name: string, lessons: string[] }): boolean {

Обьектный тип указан через запятую, а нужно через двоеточие. Вот из урока:

"Чтобы принять такой объект в функцию как параметр, нужно указать его структуру в описании функции:
// Свойства в описании типа разделяются через точку с запятой (;) function doSomething(user: { firstName: string; pointsCount: number; }) { // ...
}"

Также в этом же примере из урока в параметре pointsCount после него не требуется точка с запятой - это насколько я понимаю инлайновая запись обьекта. В офф. доке не ставят https://www.typescriptlang.org/docs/handbook/2/objects.html

Обработать замечания

Замечания от Сергея М

  • Странная штука с уроками в TS. Студент знакомится с Union:

    При том между 3 и 25 уроком столько раз используются юнионы, что непонятно зачем уроки в середине курса. Их тогда уж логично сделать третьим уроком и дальше использовать спокойно. А 25й урок словно вообще не про то должен был быть

  • 29 https://code-basics.com/ru/languages/typescript/lessons/intersection-types задание слишком хитрожопое, особенно на фоне остальных очень простых заданий. Тут сразу и рекурсия, и связные списки, и тесты на внимательность и при этом очень плохо подсвечена основная идея пересечений, так как тип создаётся новый почти целиком. Нужно что-то кардинально иное

    Реализуйте функцию `reverseDoubleLinkedList`, которая принимает двусвязный список с числовым полем `value` и разворачивает его.

  • 30 https://code-basics.com/ru/languages/typescript/lessons/assignability

    Урок:

    Из текста урока непонятно что за проблематика, как она решается. В коде урока задействованы две переменные, которые нигде не указываются. В функцию, принимающую строку передаётся булево значение зачем-то. Какой-то набор случайных фактов просто.

    Задание:

    Задание сформулировано так, что никакого функционала делать не нужно, просто вернуть true и false.

  • 31 https://code-basics.com/ru/languages/typescript/lessons/type-hierarcy

    Урок:

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

    Задание:

    В решении учителя используются Record и дженерики, которые ещё студенты не проходили.

    Типобезопасное решение:

    const defaultUser = { id: 0, name: '', age: 0 };
    const getUserFriends = (userResponseJSON: string, userId: number): User[] => {
      const userResponse: UserResponse = JSON.parse(userResponseJSON) as UserResponse;
    
      return userResponse.friends
        .map(([ownerId, friendId]: Friends): User => {
          if (!(userId === ownerId || userId === friendId)) return defaultUser;
          const searchId = (ownerId === userId) ? friendId : ownerId;
          const friend: User | undefined = userResponse.users.find(({ id }) => id === searchId);
    
          return friend === undefined ? defaultUser : friend;
        })
        .filter((user: User) => user.id > 0);
    };
  • 34

    https://code-basics.com/ru/languages/typescript/lessons/class-fields

    Урок:

    Задание:

    Сказано, что надо реализовать метод, а в тестах проверяются свойства. Надо или поменять тесты, или уточнить задачние.

    Вообще, зачем упражнение на создание класса, если мы изучаем типы?

  • 35

    https://code-basics.com/ru/languages/typescript/lessons/class-as-types

    Урок:

    Задание:

    В решении учителя несколько проблем:

    1. Усложнённое решение
    2. Нарушен принцип сокрытия реализации

    Так как isCopy - это служебное поле для внутренней логики класса, оно не должно быть видно снаружи пользователям этого класса. Иначе можно сделать так: new File({ name: ‘’ size: 0, **isCopy: true** }) — на функциональности это не скажется, но isCopy висит в подсказках редактора. А мы типизируем всё, чтобы редактор не подсказывал фигню.

    Поэтому на входящие параметры должен быть тип или интерфейс на весь класс, а isCopy остаётся чисто приватным методом и используется только внутри, пользователь его не передаёт. Упрощённое и правильно типизированное решение:

    type OpitonName = string;
    type OpitonSize = number;
    type FileOptions = { name: OpitonName, size: OpitonSize };
    
    class File {
        name: OpitonName;
        size: OpitonSize;
        private isCopy: boolean;
    
        constructor(options: FileOptions) {
            this.name = options.name;
            this.size = options.size;
            this.isCopy = (options instanceof File);
        }
    
        toString(): string {
            const copyString = this.isCopy ? '(copy) ' : '';
            return `${copyString}${this.name} (${this.size} bytes)`
        }
    }
  • Разбор структуры текста

    В программировании языки делятся на две большие группы: динамически типизированные и статически типизированные. Преимущества TypeScript появляются за счет того, что JavaScript относится к первой группе. У таких языков есть интерпретатор — программа, которая выполняет код построчно без предварительного анализа:
    Два примера кода
    TypeScript относится к статически типизированным языкам, поэтому работает по-другому. Перед запуском кода этих языков на выполнение его нужно скомпилировать.
    Во время компиляции проверяется, что программа типобезопасна — не содержит ошибок, подобных примеру выше. Если компилятор нашел несоответствие типов, то он останавливает компиляцию и выводит предупреждения о том, где типы не сходятся. Т

    Структура текста получается:

    • Вводится понятие двух вещей в двух классах. Потом сказано что преимущества второй вещи в том что первая в другом классе :wwhat: Потом поясняется первый класс вещей.
      Потом блоки кода
    • Потом возвращение ко второй вещи.

    Ты в итоге пытаешься проследить логику, прыгая по тексту глазами вверх-вниз. Хотя можно было вводить термины и примеры постепенно:

    • Есть две группы языков
    • JavaScript относится к динамическим - это значит, что...
    • Преимущества динамического
    • Недостатки динамического
    • TypeScript относится к статическим - это значит, что...
    • Преимущества динамического
    • Недостатки динамического
  • Почему вдруг появился фронтенд и команды разработчиков?

    Какие особенности у TypeScript
    Сейчас у фронтенд-приложения могут быть большие команды в десятки и сотни разработчиков.

  • Про установку

    Поэтому установка TypeScript предельно простая:

    Ещё текст

    Также можно использовать более простой способ. Можно поставить пакет ts-node, который выполняет одновременно компиляцию и запуск

    Кажется, автор говорит про более простой способ, чем установку typescript, но на самом деле, он предлагает это:

    Чтобы не компилировать код каждый раз для запуска через node, можно поставить утилиту ts-node...

Добавить возможность использовать ссылки на локальные картинки в уроке

Сейчас, чтобы добавить картинку в урок нужно заливать её на хостинг и вставлять полную ссылку на неё. Что не удобно и черевато потерями картинок.

Сделать возможность хранения картинок в папке с самим уроком, например в подпапке assets и указания относительной ссылки вида assets/picture.jpg в уроке.

Опечатка урок 34

class Point {
x = 0;
y = 0;
}

const p = new Point();
console.log(p); // (0, 0)

Последняя строка - должно быть:
console.log(p); // { x: 0, y: 0 }

Пересмотр уроков курса с учетом поправки

В уроке про алиасы типов есть такой абзац:

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

Не понимаю, зачем учить неправильно. Создать тип - это создать тип, создать алиас типа - это создать алиас типа и никак иначе. Подход, что "правильно вот так, но мы будем придерживаться общепринятого называния" порождает следствия, когда разработчики будут говорить по-разному и потом путаться, хотя речь шла об одной и той же вещи.

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

Добавить информацию про satisfies в курс по TypeSctipt

Здесь используется оператор satisfies, но нигде про него не рассказывалось, возможно стоит добавить немного информации про него в курс (а может и не надо, потому что оператор легко гуглится или достаточно дать ссылку на документацию)

Тип Void :: Описание метода push()

Метод `push()` возвращает индекс добавленного элемента. Если бы `forEach()` требовал от колбека возврат `undefined`, то такой код привел бы к ошибке компиляции. Его пришлось бы переписать, например, так:

Написано что метод push() возвращает индекс добавленного элемента, но в JS он возвращает новую длину массива.

Урок 11, Система модулей. Добавить комментарий о том, что namespace-ы расходятся с нынешней концепций TS

В этом интервью говорится, что namespace-ы бы не добавляли в язык, если бы на тот момент была система EcmaScript модулей
https://www.youtube.com/watch?v=tXK50czRbdA&t=990s

Так же, насколько понимаю, namepspace-ы, как и enum-ы, расширяют синтаксис языка вместо просто добавления статической проверки типов.

качество кода, перевода и текста в уроках 31, 32, 33, 34, 40, >50

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

Единственное огорчение, качество перевода после урока 30 резко падает: в тьюториалах 31 (черепашка), 32 (json), 33 (кошелёк) текст объяснения и заданий очень сложно понять, так как выполнялся грубый машинный перевод с английского без последующих правок переводчиком :(.

Урок 34 (классы) словесное месиво.

урок 40 в самом конце материала:
console.log(clock12.render()); // => '00 : 00 AM'
должно быть 12:00 AM (00:00 в системе AM, PM не существует, только 12:00)

В уроках после 50 в коде! примеров опечатки.

Всё приходится поднимать самому, это не учебное пособие.

Честное GitHub issue

Спасибо за предложение, информация полезная, но для решения текущего задания точно не нужна, пока урок, где эта информация могла быть бы уместна не написан

    Спасибо за предложение, информация полезная, но для решения текущего задания точно не нужна, пока урок, где эта информация могла быть бы уместна не написан

Originally posted by @bondiano in #124 (comment)

Ссылка на урок - https://code-basics.com/ru/languages/typescript/lessons/type-annotations#editor
Как это не нужна... В уроке аннотация типов, в решении учителя используется (as number[]):
// BEGIN
function compact(items: (number | null)[]): number[] {
return items.filter((item) => item !== null) as number[];
}
// END

Без него тесты не проходят и про него нигде не упоминается.
Что бы ученик мог решить самостоятельно задание он должен о нём знать.

Обработать замечания студентов

  • Перегрузка функций. https://github.com/hexlet-basics/exercises-typescript/blob/main/modules/20-functions/85-function-overloads/description.ru.yml

    Мне кажется, в задаче к этому уроку не имеет смысла реализовывать перегрузку функции, потому что у нас тип входных данных не меняется. Есть просто один необязательный параметр. Функция совершенно спокойно реализуется в одной единственной версии с этим необязательным параметром без перегрузки, и тест проходит. Если в решении учителя удалить первые две строки кода (перегрузку), ровным счётом ничего не поменяется и всё будет так же работать. Перегрузка имела бы смысл, если бы тип данных аргументов мог бы быть разным.
    https://ru.hexlet.io/topics/87857

  • Иерархия типов https://github.com/hexlet-basics/exercises-typescript/blob/main/modules/25-types/50-type-hierarcy/description.ru.yml

    Два вопроса по теории:

    let unknownValue: unknown = 1; const two: 2 = 2; const notTrue: false = false;
    
    unknownValue = two; unknownValue = notTrue; // OK
    

    Почему мы в переменную типа unknown можем присвоить значение типа number или литерального типа 2, а потом в эту же переменную присваиваем значение типа boolean или литерального false? То есть переменная типа unknown после присвоения ей какого-то первого конкретного значения так и остаётся unknown и позволяет дальше присваивать что угодно? Чем тогда unknown отличается от any? Я этого, честно сказать, так и не понял.

    
    const two = num as 2; // Явное нисходящее приведение
    
    const three = 3 as const; // Приведение к литеральному типу — нисходящее
    

    не понял, что такое восходящее и нисходящее приведение. Что конкретно делает, например, const three = 3 as const ? Какого типа будет константа three?

Add return type

В уроке Именованные функции есть такое утверждение:

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

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

Опечатка урок 35

В тексте
При TypeScript будет требовать явно требовать экземпляр класса, если у него есть приватные поля:

Должно быть:
TypeScript будет явно требовать экземпляр класса, если у него есть приватные поля:

Исправить глагол

Урок 2

исправить глагол в "Код выше не только не запустится на исполнение, но и не прошел компиляцию": не прошел --> не пройдет

image

Добавить ответы на задачи

Не хватает кнопки "Подсказка" как сделано на Хекслете: когда сталкиваешься с проблемой решения задачи, то ответ учителя никак не посмотришь и потом себя не зарефакторишь. В слаке можно долго жддать и не дождаться помощи

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.