Задать вопрос
  • Как типизировать в ts?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Вопрос конечно в духе "я его того, а он мне нихрна, чаво это он". Где конкретика блин? Что именно за ошибка? Любая ошибка TS - это "ошибка типов", он для этого и существует. Что у тебя в route?

    Но окей, предположим, что route у тебя - это текущий роут vue-рутера, тогда ошибка у тебя скорее всего выглядит как-то так:
    TS7053: Element implicitly has an 'any' type because expression of type 'RouteRecordName' can't be used to index type '{ first: string; second: string; }'.   No index signature with a parameter of type 'string' was found on type '{ first: string; second: string; }'.

    Собственно прочитав текст ошибки можно уже догадаться, в чём проблема: у (неявно выведенного за отсутствием явного объявления) типа объекта pages есть ключи типа 'first' | 'second' | ..., но нет index signature типа string, т.е. не указано, что ключом может быть любая строка, а не только конкретные'first' | 'second' | ....
    route.name же после проверки на пустоту имеет тип string | symbol. Ты не можешь у объекта с чётко ограниченным набором ключей брать значение по произвольному строковому/символьному.

    Прямое решение в лоб:
    Задать тип pages позволяющий рандомные ключи, например
    const pages: Record<PropertyKey, string> = {
      first: 'Первая',
      second: 'Вторая',
      ...
    }

    Всё сразу заработает, но это не спасёт тебя от ошибок(например опечаток).


    Не менее прямой вариант
    (но с другой стороны):
    Кастануть нужный тип руками: ... = pages[route.name as keyof typeof pages]
    Ведь мы уверены, что name в route всегда будет одним из ключей pages. Уверены же?..

    Энтерпрайз решение(ничем не лучше предыдущих, зато выглядит солидно):
    Твой файл routes.ts:
    export enum ERoutes {
      FIRST = 'first',
      SECOND = 'second'
    }
    
    const routes = [
      {
         name: ERoutes.FIRST,
         ...
      },
      {
         name: ERoutes.SECOND,
         ...
      },
      ...
    ]

    В коде:
    const pages: Record<ERoutes, string> = {
      [ERoutes.FIRST]: 'Первая',
      [ERoutes.SECOND]: 'Вторая',
      ...
    }
    
    ... = pages[route.name as ERoutes]


    Надмозговое решение("как батька"):
    Твой файл routes.ts:
    const routes = [
      {
         name: 'first',
         ...
      },
      {
         name: 'second',
         ...
      },
      ...
    ] as const satisfies ReadonlyArray<ReadonlyRouteRecordRaw>;
    
    type ReadonlyRouteRecordRaw = Omit<RouteRecordRaw, 'children'> & {
      children?: ReadonlyArray<ReadonlyRouteRecordRaw>;
    };
    
    type ExtractNames<Route> = Route extends { name: infer Name } ? Name : never;
    type FlattenChildren<Route> = Route extends { children: ReadonlyArray<infer Children> }
      ? FlattenChildren<Children> | Route
      : Route;
    
    // с помощью магии ts вытаскиваем в тип RouteNames все заданные у нас имена маршрутов
    export type RouteNames = ExtractNames<FlattenChildren<typeof routes[number]>>;
    
    // с помощью магии же прокидывем их прямо в декларацию vue-router
    declare module 'vue-router' {
      export interface RouteLocationNormalizedLoaded {
        name: RouteNames | null | undefined;
      }
    }

    satisfies
    satisfies - новая фича ts 4.9, в предыдущих версиях того же можно добиться сделав обёртку вида:
    const narrowRoutesTypeWrapper = <T extends ReadonlyArray<ReadonlyRouteRecordRaw>>(routes: T) => routes;
    const routes = narrowRoutesTypeWrapper([ ... ] as const);

    И твой код заработает вообще без изменений (если в pages есть все нужные ключи).)
    Однако для удобства можно написать так:
    const pages: Record<RouteNames, string> = {
      first: 'Первая',
      second: 'Вторая',
      ...
    }
    Ответ написан
    Комментировать
  • Как работает оператор &?

    То что вы написали в вопросе и в комментарии к моему встречному вопросу - это две совершенно разные вещи.

    То что в вопросе:
    const myVar = ClassCat & ClassDog;
    Тут работа идёт со значениями и & - это побитовое И.

    А вот кусок кода из вашего пояснения:
    export type CatDocument = Cat & Document;
    1. Это Typescript. В JS нет никакого Export type
    2. Тут работа идёт уже с типами (Не со значениями!). & - это пересечение типов
    CatDocument - это пересечение типов Cat и Document.

    На практике это значит, что переменная, которая имеет тип CatDocument должна иметь все поля из Cat и из Document, если Cat и Document - это объекты.
    Ответ написан
    Комментировать
  • Насколько хорошо бэкенд-разработчик должен знать SQL?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    Ожидаю уверенного владения SQL как минимум в стандарте 2003, а также понимание реляционной теории. Ну и надо понимать, что кандидатов джунского уровня сотня в неделю, чтобы пробиться на место, нужно выделяться среди других, поэтому чем больше знаешь, тем лучше. Покажешь умение читать планы выполнения - плюс, показал владение оконными функциями - ещё плюс, рассказал про WAL при обсуждении транзакций - снова плюс, смог к этому ещё и объяснить про MVCC - совсем молодец. И т.д. и т.п.
    Ответ написан
    Комментировать
  • Почему после сборки приложения картинки не сохраняются?

    @falconandy
    1. Можно использовать embed, чтобы вшить картинку в бинарник.
    2. Но если посмотреть исходники beeep, то окажется, что библиотека работает с файлами и пока не умеет работать с массивом байт (Support for supplying image-data as a blob).
    3. Поэтому вы можете вшить картинку, но перед вызовом beeep.Notify вам надо будет сохранить вшитую картинку во временный файл и передать в beeep.Notify путь к нему.
    Ответ написан
    52 комментария
  • Как задать задержку для fetch при скачивании более 4000 фото?

    RAX7
    @RAX7
    Помимо случайной задержки нужно еще ограничить количество одновременных запросов, примерно так:
    function randomDelay(min = 250, max = 750) {
      return new Promise((resolve) => {
        const ms = Math.random() * (max - min) + min;
        setTimeout(resolve, ms);
      });
    }
    
    function downloadAll(urls, limit = 4) {
      return new Promise((resolveAll, rejectAll) => {
        const result = [];
        const iter = urls.entries();
        let fulfilled = 0;
    
        const next = () => {
          const { done, value } = iter.next();
    
          if (done) {
            if (fulfilled === urls.length) {
              resolveAll(result);
              return;
            }
    
            return;
          }
    
          const [index, url] = value;
          const onFulfilled = (val) => {
            result[index] = val;
            fulfilled += 1;
            next();
          };
    
          randomDelay()
            .then(() => fetch(url))
            .then(onFulfilled, rejectAll);
        };
    
        for (let i = 0, l = Math.min(limit, urls.length); i < l; i++) {
          next();
        }
      });
    }
    
    const urls = Array.from(
      { length: 100 },
      (_, i) => `https://jsonplaceholder.typicode.com/todos/${i + 1}`
    );
    
    (async () => {
      const responses = await downloadAll(urls, 2);
      const data = await Promise.all(responses.map((r) => r.json()));
      console.log(data);
    })();
    Ответ написан
    1 комментарий
  • Как задать задержку для fetch при скачивании более 4000 фото?

    sergiks
    @sergiks Куратор тега JavaScript
    ♬♬
    Можно в N параллельных «потоков» скачивать. В каждом случайная пауза перед очередным URL:
    const N = 3;
    
    const delay = ms => new Promise(res => setTimeout(res, ms));
    
    const next = () => {
      if (items.length > 0) {
        return download(items.shift())
          .then(delay(500 + Math.floor(Math.random() * 500))) // случайная пауза между закачками
          .then(next);
      }
    };
    
    const works = Array.from({ length: N }, () =>
      Promise.resolve()
        .then(next)
        .catch(console.error)
    );
    
    Promise.all(works).then(() => console.log('All Done'));
    Ответ написан
    1 комментарий
  • Как проверить открытие письма?

    shurshur
    @shurshur
    Сисадмин, просто сисадмин...
    Из соображений безопасности открытие ресурсов по внешним ссылкам многие почтовые клиенты и почтовые сервисы не делают вообще. Тем более когда речь явно идёт о картинке размера 1x1, которую могут игнорировать намеренно (лучше уж тогда не указывать размеры, пусть клиент скачает картинку эту 1x1 и узнает размер только после этого).

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

    Или, как вариант, картинку почтовый сервис получателя может скачать заранее и положить в кэш, что также ничего не означает о получении письма. Её также может скачать антивирус почтового сервиса или получателя, чтобы проверить.

    Я всегда принципиально отказываюсь от всех подтверждающих получение действий и фокусов, потому что если отправитель ПОЛЕНИЛСЯ приаттачить все картинки к письму - то значит я посмотрю на его письмо без картинок и по ссылкам переходить не буду вообще. Не заслужил. Ничего ценного в таких письмах я ещё ни разу не видел.

    Единственное, для чего все эти средства помогают - примерно оценивать степень прочтения в сравнении с предыдущим опытом. Скажем, вчера письмо прочитало 30% получателей, это может означать что его прочитало, например,на самом деле 60%, но лишь половина подвержена трекингу. А если сегодня прочитало 10%, значит, что-то случилось: письмо хуже дошло до получателей, письмо хуже привлекло их внимание... (Все цифры, конечно, от балды, они имеют иллюстративный характер)

    Да и вообще, в наше время почту читает всё меньше людей.
    Ответ написан
    Комментировать
  • Какие существуют сервисы для интернет-аквайринга в 2022 для физлиц РФ?

    svob
    @svob
    Фрилансер, текстовик широкого профиля
    Самозанятый может просто на банковский счет принимать. Во многих банках есть услуга автоматического формирования чеков о доходах самозанятого на все поступления по номеру конкретной карты. В смысле, эта опция к карте привязывается.
    Ответ написан
    1 комментарий
  • Не хожу на работу, но меня не увольняют и не платят зарплату, как быть?

    BasiC2k
    @BasiC2k
    .NET developer (open to job offers)
    У Вас отличный кейс! Отличный в плане того, что есть возможность получить всю заработную плату с дня заключения трудового договора, до его расторжения. Перечитайте трудовой договор, проконсултируйтесь с юристом. И если Вас что-то не устраивает - всегда можно уволиться )
    Ответ написан
    2 комментария
  • Что должен знать Middle+ разработчик Go?

    dimonchik2013
    @dimonchik2013
    non progredi est regredi
    3-5 коммитов в популярные либы достаточно
    Ответ написан
    4 комментария
  • Что должен знать Middle+ разработчик Go?

    opium
    @opium
    Просто люблю качественно работать
    так ты ж мидл мы у тебя должны спрашивать
    Ответ написан
    Комментировать
  • Дефолтное значение, пока полностью не загрузился Vue?

    Fragster
    @Fragster
    помогло? отметь решением!
    Теоретически можно сделать как-то так:
    <div id="app">
      <div v-cloak>{{ price }}</div>
      <div class="uncloak">0</div>
    </div>

    [v-cloak] { display: none }
    [v-cloak] + .uncloak { display: block }
    .uncloak { display: none }

    но скорее всего будет немного моргать в момент переключения. Как-то так: https://codepen.io/FragsterAt/pen/wvXNYax
    Ответ написан
    2 комментария
  • Как создать собственную тему для чужих сайтов?

    MrDecoy
    @MrDecoy Куратор тега CSS
    Верставший фронтендер
    Внедряться в сайт оно не будет.
    Можно только локально, то есть конкретно у вас в браузере переопределить стили. Такое расширение уже есть. Вы ставите себе это расширение, пишите в нем стили и они применяются к сайту.
    Всё что нужно сделать - написать эти стили.
    Но работать это будет до ближайшего обновления сайта. Я так писал свои стили для вк, когда он на новый дизайн перешёл, чтоб старый дизайн вернуть. Держалось в среднем несколько недель. Потом что то нужно было править. А если сайт как инстаграм, например, когда имена классов генерируются, то полагаться можно только на иерархию разметки, а это адище такие стили писать.

    Если просто цветовую гамму сменить - это можно. Если серьёзно что-то менять хотите, то гиблое дело.
    Ответ написан
    Комментировать
  • На чем делать UI для Windows в 2022 году?

    MAUI - это масштабное обновления xamarin-а по сути. ИМХО без поддержки Linux его кроссплатформенность мало чего стоит.
    WPF - это нативная технология при этом с WPF тебе доступны всякие сторонние и родные контролы. В том числе самые новые от WinUI 3.
    UWP превратился в WinUI 3
    Avalonia - кроссплатформа. "Как WPF но лучше", но без поддержки контролов от WPF или WinUI, но есть много свободных вполне неплохих. Да и система стилей достаточно удобная

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

    На втором месте наверное AvaloniaUI смущает что на нем каких то больших проектов.

    Есть много разных проектов, в том числе крупных и коммерческих, и от именитых компаний.
    https://avaloniaui.net/Showcase

    Так как программа небольшая я склоняюсь все быстро сделать на Windows Forms, в 2022 году кто то стартует на нем новые проекты?

    Если ты делаешь что-то небольшое и чисто для себя, и ты не умеешь работать с XAML и нет времени на освоение - нет причин не использовать Winforms. Да, он имеет проблемы с производительностью, да он не очень красивый, да винформы не очень легко поддерживать. Но является ли это реальной проблемой для вашего проекта?

    В общем вот мой топ-чарт:
    1. Если дёшево и сердито - Winforms (остальное - если нужен нормальный дизайн)
    2. Если кроссплатформу - Avalonia
    3. Если нужно на телефоны - MAUI (хотя Avalonia уже можно заставить работать на Android)
    4. Если хочется в новый дизайн винды - WinUI 3
    Ответ написан
    6 комментариев
  • Как с помощью регулярного выражения отделить символы с большой буквой, добавив пробел?

    0xD34F
    @0xD34F Куратор тега JavaScript
    str.split(/(?<=\S)\s*(?=[А-ЯЁ])/).join(' ')
    
    // или
    
    str.replace(/(?<=\S)(?=[А-ЯЁ])/g, ' ')
    
    // или
    
    str.replace(/(\S)(?=[А-ЯЁ])/g, '$1 ')
    
    // или
    
    str.replace(/[А-ЯЁ]/g, (m, i) => i && str[~-i] !== ' ' ? ' ' + m : m)
    Ответ написан
    1 комментарий
  • Как лучше объединить элементы массива в строку?

    0xD34F
    @0xD34F
    $toStr = fn($arr) => implode('', array_map(fn($k) => "[$k:]$arr[$k][:$k]", array_keys($arr)));
    print_r(array_map($toStr, $lang));
    Ответ написан
    1 комментарий
  • Как реализовать смену текста при переключении между radio button?

    0xD34F
    @0xD34F Куратор тега Vue.js
    data: () => ({
      meetupId: null,
      meetupData: null,
    }),
    watch: {
      meetupId(val) {
        fetch(`https://course-vue.javascript.ru/api/meetups/${val}`)
          .then(r => r.json())
          .then(r => this.meetupData = r);
      },
    },

    <label v-for="i in 5">
      <input type="radio" name="meetupId" :value="i" v-model="meetupId">
      {{ i }}
    </label>
    <pre>{{ meetupData }}</pre>
    Ответ написан
    Комментировать
  • В чем разница между способами тестирования (в контексте web и php)?

    VoidVolker
    @VoidVolker
    Dark side eye. А у нас печеньки! А у вас?
    Опишу простыми словами для упрощения понимания.

    модульное тестирование

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

    интеграционное тестирование

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

    функциональное тестирование

    Очевидно, что тестируются конкретные функции, которые есть в техническом задании. Например: когда пользователь нажимает кнопку "купить" в карточке товара - товар добавляется в корзину.
    какими инструментами оно делается?

    Инструментами автоматизации GUI - для сайтов это Selenium и браузеры. Для десктопных/мобильных приложений аналогичные решения.

    приемочное тестирование

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

    "Бизнес" заказал в "Конторе" разработку сайта, выдал ТЗ, контора сделала сайт, бизнес заплатить денег обещал. Как бизнес проверит что контора сделала именно то, что он хотел? Через приемочное тестировние - бизнес получает доступ к сайту и проверяет, что сайт именно такой, какой он заказывал в ТЗ, а не тот, который сделали индусы за доширак. Если в ТЗ указан конкретный список тестов/фич - используется этот список или так, как прописано в ТЗ само тестирование. Само тестирование проводит соответствующий специалист (инженер отдела качества) - тыкает все кнопочки, нажимает менюшечки и говорит начальству "все окей, подписывай и платим им деньги" или "вот тут и тут не окей, не подписывай, денег не давай". Реальный пример: была заказана и собрана станция спутниковой связи, на приемке были представители заказчика и исполнителя, была толстая пачка бумаги на несколько сотен страниц, по которой первые проверяли что все работает именно так, как там написано в течении нескольких недель (плюс-минус), а вторые исправляли косяки показывали что все окей, потом все поставили свои галочки и крестики и разъехались по домам.

    E2E - тут тестируется чрез браузер, с помощью Mocha и тп, те тестируются "требования бизнеса к приложению", тестируются пользовательские сценарии.. а в чем отличие от функциональных тестов тогда?

    Сквозное тестирование. Это полная проверка от начала и до конца. Отличие от функционального в том, что это более комплексный тест. Если функциональное тестирование - это проверка конкретной функции, тот сквозное - работа всего приложения, т.е. более комплексное. Например, E2E тест приложения для загрузки файла на сервер: тест включает в себя запуск приложения, авторизация пользователя, выбор файла, указание мета информации, загрузку файла на сервер, выход из приложения. Вот тут неплохая статья на хабре: https://habr.com/ru/company/otus/blog/681066/

    Совсем запутался, с unit только понятно, а как уложить и разделить остальные?

    60da68c37e576762375008e5_thumb-image.png
    Картинка отсюда: https://www.rainforestqa.com/blog/the-layers-of-te...
    Ответ написан
    Комментировать
  • Как правильно находить готовые коды, плагины на разных языках?

    AgentSmith
    @AgentSmith
    Это мой правильный ответ на твой вопрос
    Мда. С такой грамотностью далеко не уйдёшь... ПредпрИниматель...
    Я дам простой ответ - предприниматель сам должен уметь находить ответы на вопросы, которые ты здесь задаёшь.
    Ты занимаешься не своей работой."Куски кода искать" должен не руководитель, а разработчик, это его работа и его профессия, за это ты платишь ему деньги
    Ответ написан
    5 комментариев