Задать вопрос
  • Норм ли сборка ПК?

    WblCHA
    @WblCHA
    Оперативная память Silicon Power Xpower Zenith 32 ГБ;

    2 плашки?
    Написано
  • Как правильно именовать компоненты форм?

    WblCHA
    @WblCHA
    Кирилл Щевелев, ну, как правило всё привязано к папочке пейджс, от неё да, избавится не особо получится, но это не есть плохо, у тебя всё равно централизованное место будет, просто в сами компоненты со страницами не стоит тащить логику, по возможности.
    Но по факту всё это индивидуально, это моё мнение из личного опыта.

    Гляну за эти атомик и фсд)

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

    WblCHA
    @WblCHA
    Кирилл Щевелев,
    Последние вопросы про папку forms и components вообще не понял... Понятное дело, что в проекте будет папка components/user.

    Не думаю, что предыдущий оратор подразумевал это, но по факту лучше не использовать дефолтную структуру папок аля компонентс, пейджс, хукс, утилс и т.д. Она, откровенно говоря, только для туду листа годится.
    Сейчас при добавлении новых страниц у тебя будет каша в компонентах и других папках.
    Посмотри на атомик дизайн, фсд и другие методологии. Но основная суть, дели на полноценные блоки. То, что касается юзера, в одной папке, то, что касается формы юзера, в другой, общие компоненты отдельно. И делить не по сущности (компонент, хук, функция), а по назначению (юи, моделс, либ). Как именно это всё будет называться не принципиально, главное чтобы было логично.

    И уже после этого вопрос с именованием файлов уже сам по себе начнёт решаться. Там уже хоть просто воркс, эдьюкейшен и т.д. называй. Хотя лично я предпочитаю иметь максимально полное название, иначе потом навгация по файлам не очень удобная становится, когда куча одноимённых файлов.
    Написано
  • Как правильно именовать компоненты форм?

    WblCHA
    @WblCHA
    godsplan,
    я бы конечно начал с того что перестал бы именовать название файлов camelCaseом...

    А вот с этого момента поподробнее. С каких пор камел и паскаль кейсы, кои являются стандартом во всём жс, стали некомильфо?

    вы как будто мыслите не в рамках компонентного подхода, а в рамках созависимых чанков.
    Почемму UserAvatar а не просто Avatar?
    Что такое Education и как я должен понять из названия файла что этот файл делает. ответ - никак.

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

    Так же возник вопрос, а что будет если в папку forms положить еще форму?Или в папку components запихать что-то отличное от сущности юзера?

    А вот это уже нормальные вопросы.
    Написано
  • Как небольно избавится от as const для обхода ошибки 'type string is not assignable to type keyof' и '"center" | "right" | "left" | undefined'?

    WblCHA
    @WblCHA
    Антон Антон,
    интересно, но всё равно в каждую строку надо дописывать "мусор"

    Это бросается в глаза только когда мало параметров прописываешь, а так одним больше, одним меньше, зато больше контроля.

    satisfies, к сожалению, не типизирует содержимое, и, например, не работает типизация параметра format и field, когда она функция

    Ну, да, добавь тогда `as const` перед `satisfies`.)

    А вообще в идеале отдельную функцию под это дело написать надо, типа такой (это для mantine):
    export const createTableColumnsBase = <GData>() => {
      const columns: Record<string, Column<GData, unknown>> = {}
    
      const getActions = <GColumns>() => ({
        add: <K extends string, V>(id: K, column: Column<GData, V>) => {
          columns[id] = column as Column<GData, unknown>
    
          return getActions<GColumns & Record<K, Column<GData, V>>>()
        },
        done: () => columns,
        doneTyped: () => columns as GColumns
      })
    
      return getActions<unknown>()
    }

    Зачем? Так ты за счёт поле филд (или селектор) типизируешь все передаваемые калбеки и компоненты. С массивом это не сделать. Вернее можно, в целом, но костыльно и сам тс не переварит тапл длинною больше 3.
    Написано
  • Как небольно избавится от as const для обхода ошибки 'type string is not assignable to type keyof' и '"center" | "right" | "left" | undefined'?

    WblCHA
    @WblCHA
    Антон Антон, для справки, дефолтные парамсы лучше не столько из-за типизации, сколько из-за возможности перезаписать их при необходимости у конкретной колонки.
    Забей, я не обратил внимание, что ты деструктуризируешь после.
    Написано
  • Как небольно избавится от as const для обхода ошибки 'type string is not assignable to type keyof' и '"center" | "right" | "left" | undefined'?

    WblCHA
    @WblCHA
    Антон Антон, не используй мап, он тебе ненужен здесь. Используй дефолтные пропы:
    const defaultColumnParams: Partial<QTableColumn<ProfileEntity>> = {
      align: 'left'
    }
    
    const columns: QTableColumn<ProfileEntity>[] = [
      { ...defaultColumnParams, name: 'id', label: 'id', field: 'id' },
      { ...defaultColumnParams, name: 'first_name', label: 'Имя', field: 'first_name', sortable: true },
      { ...defaultColumnParams, name: 'last_name', label: 'Фамилия', field: 'last_name', sortable: true, align: 'right' },
    ]


    Но если всё же сильно хочется, то типизируй иначе:
    const columns = ([
    { name: 'id', label: 'id', field: 'id'},
    { name: 'first_name', label: 'Имя', field: 'first_name', sortable: true },
    { name: 'last_name', label: 'Фамилия', field: 'last_name', sortable: true, align: 'right' }
    ] satisfies QTableColumn<ProfileEntity>[]).map((c): QTableColumn<ProfileEntity> => ({align: 'left', ...c}))
    Написано
  • Как заставить typescript поверить, что в объекте есть свойство?

    WblCHA
    @WblCHA
    Антон Антон, если нужна проверка именно на нулл и андефайнд, то да, нужен тайпгуард. Но если ты уверен, что ид не может быть пустой строкой или нулём, то нет необходимости строго сравнивать:
    interface SomeDataCreate {
      id?: null
      [key: string]: unknown
    }
    
    interface SomeDataUpdate {
      id: number | string
      [key: string]: unknown
    }
    
    export async function upsert(
      path: string,
      data: SomeDataCreate | SomeDataUpdate
    ) {
      if (data.id) {
        return update(path, data)
      } else {
        return create(path, data)
      }
    }

    Впрочем, ничего не мешает и напрямую проверить невалидные значения:
    if (data.id && data.id !== "" && data.id !== 0) {
    Написано
  • Как заставить typescript поверить, что в объекте есть свойство?

    WblCHA
    @WblCHA
    Антон Антон, id: never сделай опциональным, иначе объект этого типа не создашь и не передашь.
    А ругается потому, что без id: never у тебя этот самый проп ид подпадает под [propName: string]: unknown, то есть тоже самое, что: id?: unknown
    Написано
  • Как заставить typescript поверить, что в объекте есть свойство?

    WblCHA
    @WblCHA
    Антон Антон, сори, я на солнышке перегрелся, похоже. Какой ещё тайпоф?
    if (data.id !== undefined) {
        return update(path, { id: data.id, ...data })

    Это проверка проверяет само свойство и его тип перестаёт быть андефайнд, но этот костыльчик необходим, потому что типизация не совсем правильная.
    По факту тебе надо юнион здесь и тогда тс поймёт, что дата может быть только одного типа после проверки.
    export async function upsert(
      path: string,
      data: { id?: never } | { id: number | string }
    ) {
      if (data.id !== undefined) {
        return update(path, data)
      } else {
        return create(path, data)
      }
    }

    Но даже это не до конца верно, потому что у тебя передаваемый объект полностью должен быть типизирован и тогда получаем что-то в этом роде:
    interface SomeDataCreate {
      name: string
    }
    
    interface SomeDataUpdate {
      id: number | string
      name: string
    }
    
    export async function upsert(
      path: string,
      data: SomeDataCreate | SomeDataUpdate
    ) {
      if ("id" in data) {
        return update(path, data)
      } else {
        return create(path, data)
      }
    }
    Написано
  • Как заставить typescript поверить, что в объекте есть свойство?

    WblCHA
    @WblCHA
    как заставить поверить typescript что свойство есть

    Так он и не спорит, что оно есть, просто ты делаешь не ту проверку.

    if (typeof data.id !== undefined) {
    Написано
  • Почему Typescript ругается на файлы js?

    WblCHA
    @WblCHA
    А на что именно он ругается? Ты спрашиваешь как исправить ошибку, но саму ошибку не написал, гениально.)
    Написано
  • Почему Typescript ругается на файлы js?

    WblCHA
    @WblCHA
    Не то, чтобы это на что-то влияло, но зачем создавать скрипт для создания тсконфига? Тут же даже никакой логики нет, просто жс объект в джейсон преобразовывается и всё.
    Написано
  • Как перенести и улучшить данный скрипт из Stylus в Tempermonkey?

    WblCHA
    @WblCHA
    Константин Мельников, ты действительно считаешь, что тебе хоть кто-нибудь ещё поможет с таким отношением к людям? Я бы может и помог тебе написать код, но ты же не просишь тебе помочь, ты требуешь. И зачем оно мне или кому-нибудь другому надо?
    Написано
  • Как перенести и улучшить данный скрипт из Stylus в Tempermonkey?

    WblCHA
    @WblCHA
    Константин Мельников,
    а по русски можно? Что такое жс, стайлус, цссом и обезьянка?

    По русски я как раз и написал.) А английский ты вообще не знаешь? Я буквально использовал те же самые слова, что и ты. Ну ладно, кроме жс. Это JS.

    напиши как это сделать.

    Я написал. А если ты хочешь конкретное решение, то ты сайтом ошибся, с такими запросами на фриланс.
    Написано
  • Как перенести и улучшить данный скрипт из Stylus в Tempermonkey?

    WblCHA
    @WblCHA
    Этот код применяет стиль к тегу, если внутри одного из вложенных тегов есть искомый текст. А как сделать что бы стиль применялся не только к главному, но и всем вложенным тегам? В Stylus достаточно добавить * в конце селектора. А в JS как того же результата добиться?

    А зачем тебе для этого жс? В том же стайлусе создай уникальный класс с нужным тебе цссом и селектором, а в обезьянке просто вешай этот класс нужному элементу, вместо инлайн стилей, и всё.
    Написано
  • Почему не получается подключить VSCode к Remote-WSL?

    WblCHA
    @WblCHA
    WSL: Ubuntu в левом нижнем углу продолжает гореть синим.

    И что не так? Фиолетовый они давно уже убрали.
    Терминал какой открывается? Если баш, то всё очевидно.
    Можешь ещё в настройки и посмотри, есть вкладка настроек убунту или нет.

    И совет, если держишь все проекты в всл, то добавь в настройки юзера:
    "window.title": "Not WSL: ${dirty}${activeEditorShort}${separator}${rootName}${separator}${appName}",

    и в настройки убунту добавь:
    "window.title": "${dirty}${activeEditorShort}${separator}${rootName}${separator}${appName}"

    Так ты всегда будешь уверен что именно у тебя открыто.
    Написано
  • Как в реакте правильно доставать данные из localstorage?

    WblCHA
    @WblCHA
    JSON.parse возвращает простые объекты

    Поправочка, парс тут не причём, дело в джейсоне, в нём нельзя хранить функции, коими компоненты и являются.
    Написано
  • Защищенный ТАЙМЕР для ограничения прохождения викторины по времени?

    WblCHA
    @WblCHA
    Сути дела не меняет, но...

    Таймер это счётчик - он считает пройденное кол-во единиц времени (сек, мин, часов и тд).

    Это секундомер, а таймер работает в другую сторону и сигнализирует тем или иным способом о достижении стартовой позиции.)
    Написано