• Применение двух стилей к одному значению массива js?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    По-хорошему - делаешь ещё один массив(через usememo) с уже разложенным как надо значениями и уже с ним работаешь.
    Но в целом substring каждый рендер даёт пренебрежимо мизерные накладные расходы, а вся идея React: "хреначь сейчас, оптимизируй потом(никогда)", так что делай как хочешь.)
    Ответ написан
    Комментировать
  • Поле current у ref перезаписывается, как этого избежать?

    Aetae
    @Aetae
    Тлен
    В качестве рефа для DOM элемента можно указать функцию(“callback refs”), а уж из этой функции прописать поле в реф.
    Ответ написан
    Комментировать
  • Как правильно типизировать аругменты?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    const someFunc = <
      FK extends keyof FormDataType, 
      SK extends keyof FormDataType[FK]
    >(
    	firstKey: FK, 
    	secondKey: SK
    ) => {
      ...
    }
    Ответ написан
    Комментировать
  • Как подсветить все ошибки typescript в webstorm?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    На самом деле твой вопрос: "Как подсветить ошибки типов typescript внутри шаблонов vue в webstorm".

    Ответ: никак.

    Они завязали всё на стороннюю тулзу и плагин к vscode, а не на языковой сервис typescript, потому любые ide кроме vscode в пролёте. Это очень расстраивает, да.

    У меня есть личные намётки на эту тему, но оно движется медленно и постоянно откладывается, т.к. есть задачи по-актуальней, так что в ближайшее время можно не ждать.)

    P.S. Могу пока порекомендовать плагин awesome console - он сделает кликабеьными все ссылки в консоли, включая переход к конкретной строчке.
    Ответ написан
    1 комментарий
  • React | Как убрать повторяющиеся ../ в пути?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    У тебя в тегах вебпак, а значит тебе нужны именно его алиасы.

    Если ты используешь cra, то придётся костылить, через craco или подобное.
    Ответ написан
    Комментировать
  • Как указать компилятору скопировать .json схемы?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Если ты не используешь никаких систем сборки, а только чистый tsc - то оный отвечает только и исключительно за транспиляцию самого ts, всё остальное тебе придётся делать тупо ручками: написать bash\bat\nodejs скрипт, который последовательно запустит tsc, потом запустит твой "пакет", затем просто скопирует нужные файлы в папочку dist.

    Если используешь - гугли соответствующие плагины для конкретной системы, либо пиши свои(это проще чем кажется). Например для webpack есть copy-webpack-plugin.
    Ответ написан
    1 комментарий
  • Как типизировать в 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: 'Вторая',
      ...
    }
    Ответ написан
    Комментировать
  • Как сделать блок div фоном сайта?

    Aetae
    @Aetae
    Тлен
    Всё работает, ищи проблему в своём скрипте.

    Ответ написан
    4 комментария
  • Почему задан именно такой viewbox?

    Aetae
    @Aetae
    Тлен
    Не" какой-то другой", а "какой-то неправильный". Если ты поставишь например 0 0 500 500 - всё будет работать, просто бублик будет в 10 раз меньше.
    Собственно это то, что делает viewBox - задаёт систему координат для вложенных элементов. Т.е. width у тебя 500px - эти 500px, размечены на отрезки от 0 до 50. Т.е. 1 -> 10px, r="15.9" -> r="159px". Всё просто.
    Ответ написан
    1 комментарий
  • Как компилировать ts в js используя cdn?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Есть какая-то такая хрень:
    https://www.npmjs.com/package/ts-browser-klesun
    https://www.npmjs.com/package/ts-browser

    Но правильный ответ: на проде - никак. Компиляция ts это жирнющий процесс, который будет работать очень медленно.
    Ответ написан
    Комментировать
  • Для чего нужен параметр sourceMap в tsconfig?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    webpack - это webpack, typescript - это typescript, всекаешь?

    Если нет, то поясню: это разные инструменты, которые могут прекрасно работать сами по себе и никак не пересекаться. Но в обоих случаях есть необходимость sourceMap.
    Если говорить о связке webpack и typescript, при работе в лоб webpack, как сборщик, потребляет sourceMap из typescript и генерирует из них свои.

    Сгенерированные из webpack sourceMap при отключении оных в typescript могут иметь разный вид в зависимости от настроек, плагинов и режимов: от нормальных, т.к. об этом позаботились плагины или вообще компиляция шла через babel, до полностью сломанных и бесполезных.
    Ответ написан
    Комментировать
  • Как сделать продвинутый типизированный Generic для компонента React таблицы?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Надо явно создать union:
    type ITableColumn<
      DataInterface extends object, 
      Keys extends keyof DataInterface = keyof DataInterface
    > = {
      [K in Keys]: {
        key: K;
        title: React.ReactNode;
        hasSort?: boolean;
        render?: (item: DataInterface[K]) => React.ReactNode;
      }
    }[Keys];
    Ответ написан
    4 комментария
  • Как правильно определить тип функции и события?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Мужик. Ты спик инглиш или как? MouseEventHandler переводится как "дрессировщик мышей для эвента" "обработчик событий мыши". KeyboardEventHandler как что? Правильно, "обработчик событий клавиатуры".
    Давайте подумаем, что же функция с такими типам может ожидать на вход, а? Может, соответственно, события мыши или клавиатуры(MouseEvent/KeyboardEvent)? Да не, бред какой-то.

    Но окей, дальше мы назначили пропсам интерфейс, где getCity таки имеет такой тип. И куда же мы передаём этот getCity? А передаём мы его в onSubmit. Скажи же мне, друже, submit - это событие клавиатуры? Или может быть это событие мыши? Ты уверен? Вот и мне кажется что нет.
    Ответ написан
  • Пишу первый раз на реакте, в чем проблема?

    Aetae
    @Aetae
    Тлен
    Вот это вот:
    root.render(
        <Header/>
    );

    Это магия под названием jsx. Она будет работать только если использовать специальные механизмы сборки, которые превратят сие непотребство в нормальный javascript.

    Если же ты хочешь просто вставить свой код на страницу без предвариательных танцев, то тебе придётся писать на чистом javascript, условно так:
    <script src="index.js" type="module"></script>
    import Header from './Header.js';
    
    const domContainer = document.querySelector('#container');
    const root = ReactDOM.createRoot(domContainer);
    root.render(
      React.createElement(Header)
    );

    function Header() { 
      return React.createElement('div', null, 'hsas')
    }
    export default Header;
    Ответ написан
    4 комментария
  • Почему при выносе массива из цикла в глобальную переменную, сортировка имеет разную вероятность?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    В первом случае ты сортируешь уже отсортированный массив повторно(при каждой сортировке начальное состояние разное), во втором ты сортируешь каждый раз новый(начальное состояние одно и то же).

    Использование Math.random в sort в любом случае не даст нормального распределения, т.к. под капотом используется определённый оптимизированный алгоритм сортировки, к тому же браузерозаивисимый и разный для разных случаев.
    Как это всё влияет на конечный результат - одному богу известно (или дотошному математику, который засядет с сырцами браузера и распишет километровые формулы, да).
    Если нормальное распределение получилось на практике - это совпадение, а не гарантия, что так и будет впредь.

    Факт в том, что не надо использовать метод sort ни для чего, кроме его предназначения - детерминированной сортировки.

    Используй нормальный алгоритм перемешивания и будет тебе счастье.
    первый попасшийся вариант
    function shuffle( array ) {	// Shuffle an array
    	// 
    	// +   original by: Jonas Raoni Soares Silva (http://www.jsfromhell.com)
    
    	for(var j, x, i = array.length; i; j = parseInt(Math.random() * i), x = array[--i], array[i] = array[j], array[j] = x);
    	return true;
    }
    Ответ написан
    Комментировать
  • Как убрать промежутки по краям сайта?

    Aetae
    @Aetae
    Тлен
    html, body {
      margin: 0;
      padding: 0;
    }
    Ответ написан
    Комментировать
  • Почему не работает слушатель событий на элементах?

    Aetae
    @Aetae
    Тлен
    console.log.toString()
    Сайт подменяет консоль.

    Если используешь юзерскрипты, то можешь забрать консоль до того как её подменят:
    // @run-at document-start
    const myConsole = window.console;

    Если нет, но очень надо - можешь создать фрейм и забрать консоль оттуда.)
    Ответ написан
    Комментировать
  • Как использовать useSlots().default() vue3 внутри script setup?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    о какой рендер функции идет речь?

    render-function

    Это более низкоуровневый вариант работы с vue, вместо использования <template>.(под капотом <template> компилируется в render-функцию)

    Render-функцию можно возвращать из setup, можно класть в свойство render.
    При script setup, можно сделать так:
    <template>
      <div>
        <render/>
      </div>
    </template>
    
    <script setup lang="ts">
      import { h, useSlots } from 'vue'
    
      const slots = useSlots();
      const render = () => {
        return h('div', slots.default());
      };
    </script>

    Но не нужно в подавляющем большинстве случаев. Мешать всё в одну кучу - весьма опасно.
    Ответ написан
    Комментировать
  • Как улучшить качество камеры в агуляр пва?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    1. Typescript тут не при чём.
    2. Если ты используешь метод из "camera-hardware", то проблема очевидна. Если из "camera-software", то хз, должно работать.
    Ответ написан
    Комментировать
  • Как грамотно настроить алиасы импортов?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Ну собсно по хардкору:
    1. Invalidate Caches если ещё не сделал.
    2. Закрыть, удалить папку .idea, открыть чтоб распарсил заново.
    3. Создать новый проект с заведомо рабочим конфигом и перекидывать туда кусками пока не сломается и так найти виновника.
    Ответ написан