Задать вопрос
Ответы пользователя по тегу TypeScript
  • Почему JavaScript интерпретирует переменную цикла как типа string?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    TypeScript работает только на этапе компиляции. Если вы хотите использовать скомпилированную функцию в обычном javascript коде, то проверку на верность типа переданного аргумента вам надо осуществлять самостоятельно.
    Ответ написан
    Комментировать
  • Как рекурсивно принимать json через API?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Условно как-то так:
    useEffect(() => {
      const fetchData = async (url: string, data: any[] = []) => {
        const res = await fetch(url);
        const json = await res.json();
        if(json.pagination.links.next){
          await fetchData(json.pagination.links.next, data)
        }
        data.push(json.data);
        return data;
      };
      
      fetchData("https://gorest.co.in/public/v1/users").then(setData);
    }, [url]);

    в data будет массив.

    Кстати рекурсия тут не обязательна:
    useEffect(() => {
      const fetchData = async (url: string) => {
        let data: any[] = [];
    
        do {
          const res = await fetch(url);
          const json = await res.json();
    
          data.push(json.data);
    
          url = json.pagination.links.next;
        } while (url);
    
        return data;
      };
    
      fetchData("https://gorest.co.in/public/v1/users").then(setData);
    }, [url]);


    Ну и вместо any - расставить твои типы надо.
    Ответ написан
    3 комментария
  • Как сказать тайпскрипту что я жду обьект с нужными полями в jsx?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    export const Film = ({ film }: { film: IFilm ): ReactElement => {
      return <div></div>;
    };

    А лучше:
    export const Film: React.FC<{
      film: IFilm
    }> = ({ 
      film 
    }) => {
      return <div></div>;
    };
    Ответ написан
    1 комментарий
  • Можно ли так писать код?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Всякие детали - это дело вкуса, на опасности вам в комментах указали, как и на главную проблему:
    const dataPriceAndDividendsByTicker = await responsePriceAndDividendsByTicker.json();

    Однако вот тут стоит остановиться по-подробнее.
    Даже если вы "типизируете" напрямую возврат от сервера, нет никаких гарантий, что там придёт именно то, что надо. В таком случае вы просто "обанываете" TypeScript. Для всего приходящего с сервера стоит писать хотя-бы минимальный тайпгард.
    Ответ написан
    Комментировать
  • Как сделать перечисление интерфейсов typescript?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    namespace ITMDB {
      export interface params {}; 
      export interface response {}; 
    }


    Можно и так:
    interface ITMDB {
      params: {}; 
      response: {}; 
    }

    Но тогда, увы, к конкретным ключам - только по литералам:
    ITMDB['response']
    Ответ написан
    2 комментария
  • Писать типы вначале или рассчитывать на вывод типов компилятором?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    На этот вопрос нет однозначного ответа.
    Мне нравится когда всё выводится само. Это приятно и удобно. Но нет никаких гарантий, что "само" выведется именно то, что нужно, и что ты где-то незаметно не накосячил. Потому в важных\сложных местах типы я пишу заранее. Но только в оных.

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

    Ну и есть религиозное течение "types first" но это, на мой вкус, мазахизм чистой воды. И совершенно не стоит мнимых выгод.
    Ответ написан
    Комментировать
  • Почему при компиляции typescript в js с помошью команты tsc выходит ошибка JavaScript heap out of memory?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    По умолчанию node просит минимум 512МБ.
    Можешь попробовать поиграться с --max-old-space-size, но хз. Обычно билд жрёт память гигабайтами.)
    Ответ написан
    1 комментарий
  • Как правильно инициализировать объект с разным набором полей в Typescript?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Record<string, string>
    Если ключи вдруг и в правду всегда начинаются на key, то можно так: Record<`key${number}`, string>.:)
    Если хочешь чтоб TS всегда заставлял проверять что значение там есть, то так:
    Record<string, string|undefined>
    Ответ написан
    5 комментариев
  • Почему пишет что типы несовместимы?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Ты дальше то сообщение читай:
    Type 'Applications' is not assignable to type '{ [param: string]: string | number | boolean | readonly (string | number | boolean)[]; }'.
    Index signature for type 'string' is missing in type 'Applications'

    Вот так заработает:
    export type Applications = {
      "date": string,
      "firm": string,
      "full name": string,
      "phone": string,
      "comment": string,
      "code": string
    }

    Что за хрень эта ваша Index signature гугли сам.
    Ответ написан
    Комментировать
  • Как прикрутить автогенерацию типов на чистом Rest API (без GraphQL)?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Да через сваггер. openapi-generator и прочее.
    Ответ написан
    Комментировать
  • Как метод сделать generic?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    А зачем? Ты ведь явно указываешь что результат - Observable<PayerTypes>. Другим он быть не может и ни от чего не зависит. Зачем там url?

    Или может ты имеешь ввиду что-то типа такого:
    type Urls = {
        getPayerTypes: PayerTypes;
        getNPCTypes: NPCTypes;
    }
    
    private httpGet<K extends keyof Urls>(url: K): Observable<Urls[K]> {
      return this.http.get<Urls[K]>(url)
        .pipe(
          pluck('data'),
          catchError(this.handleError)
        );
    }
    Ответ написан
    Комментировать
  • Как правильно обработать события в React+Typescript?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Ну да.
    React.KeyboardEvent - это синтетическое событие, которое генерируется в React.
    KeyboardEvent - это оригинальное событие, которое генерируется в браузере.
    KeyboardEvent лежит в event.nativeEvent у React.KeyboardEvent.

    Если вам в принципе пофиг откуда событие в функцию будет прилетать, и вас интересуют только общие свойства - сделайте так:
    const closeByESC = (event: KeyboardEvent | React.KeyboardEvent) => {

    P.S. Ну и лишних обёрток не надо: document.addEventListener('keydown', closeByESC);
    Ответ написан
    Комментировать
  • Как передать аргумент функции, для сложного объекта?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    function changeField<T extends DataType, K extends keyof T>(data:T, fieldName:K, val: T[K]) {
      data[fieldName] = val
    }
    Ответ написан
    Комментировать
  • Чем отличается в TS return Promise.resolve(); от простого return;?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Внутри async функции - ничем.
    Typescript-eslint просто не имеет соответствующего правила, а стандартное правило не знает ничего о типах.
    Либо отключай это правило, либо ублажай его.
    Ответ написан
    Комментировать
  • Как правильно реализовать дженерик?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    typescriptlang.org/play
    spoiler
    type Alph = 'Q' | 'W' | 'E' | 'R' | 'T' | 'Y' | 'U' | 'I' | 'O' | 'P' | 'A' | 'S' | 'D' | 'F' | 'G' | 'H' | 'J' | 'K' | 'L' | 'X' | 'Z' | 'C' | 'V' | 'B' | 'N' | 'M'
    
    type CamelToSnake<T extends string> = T extends `${infer S1}${Alph}${string}` ? T extends `${S1}${infer S2}` ? `${Lowercase<S1>}_${CamelToSnake<Uncapitalize<S2>>}` : T : T;
    type AsdSnake = CamelToSnake<'asdAsdAsd'> // asd_asd_asd
    
    type SnakeToCamel<T extends string> = T extends `${infer S1}_${infer S2}` ? `${Lowercase<S1>}${Capitalize<SnakeToCamel<S2>>}` : T;
    type AsdCamel = SnakeToCamel<'asd_asd_asd'> // asdAsdAsd
    
    type SnakePropToCamel<T extends PropertyKey> = T extends string ? SnakeToCamel<T> : T;
    type CamelPropToSnake<T extends PropertyKey> = T extends string ? CamelToSnake<T> : T;
    
    let camelToSnakeCase: <T extends PropertyKey>(str: T) => CamelPropToSnake<T>;
    
    type CamelObjectToSnake<T extends {[key: string]: any}> = {
      [K in keyof T as CamelPropToSnake<K>]: T[K]
    }
    
    function camelCaseObject<T extends {[key: string]: any}>(obj: T) {
      return Object.entries(obj)
        .reduce((acc, [key, value]) =>
            (acc[camelToSnakeCase(key as keyof T)] = value, acc),
          {} as CamelObjectToSnake<T>
        )
    }
    
    function camelToSnakeKeysOfArrayObject<T extends Array<{[key: string]: any}>>(arr: T) {
      return arr.map(camelCaseObject) as {
        [K in keyof T]: CamelObjectToSnake<T[K]>
      };
    }

    Основано на варианте WbICHA но поддерживает объекты разных сигнатур, типа:
    camelToSnakeKeysOfArrayObject([{
      aaAa: 1,
      bbBb: true
    }, {
      aaAa: 'ggg'
    }]);
    Ответ написан
    8 комментариев
  • Как исправить ошибку typescript?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    ...data[String(item.id)]?
    У тя самого важного куска кода не хватает:
    type 'xhr>'.
    , я так понимаю, там на самом деле Record<что-то, что-то xhr>.
    И именно там кроется точный ответ на твой вопрос.)
    Ответ написан
    Комментировать
  • Как импортировать типы из библиотеки vue?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Увы, vue-cli из коробки это не умеет. И когда последний раз смотрел в эту сторону(пару лет назад) - плагинов для этого тоже не было. 2 года - это долго, так что рекомендую погуглить.)

    Но тут ещё одна загвоздка, о которой тоже надо заранее позаботиться: тип импортированных файлов .vue по умолчанию просто Vue, без конкретизации свойств и прочего. Чтобы были нормальные ts-типы их надо отдельно генерировать. Для этого есть либа vuedts, она не идеальна, но свою работу делает.
    Если не найдёшь готовых решений - можешь чтот-то своё с этой либой намутить.)
    Ответ написан
    Комментировать
  • Во всех вакансиях по Front-End требования TypeScript?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    В первую очередь: автокомплит(когда у тя на выбор ide предлагает пару конкретно нужных вариантов, а не список из 100500 предположительно подходящих - это каеф), во вторую: отлов тупых ошибок на ранней стадии: ты просто не сможешь вызвать функцию с неверным параметром, будь то опечатка или логическая ошибка. Это прям сильно ускоряет и упрощает разработку.

    Всё остальное, типа там архитектура, чистота кода, хорошие практики бла бла бла - это так, оно может быть - а может не быть.)

    Ну и изучать толстую книжку от и до совсем не обязательно. Для начала ты можешь просто писать как в javascript, постепенно изучая новые фичи и добавляя.
    Ответ написан
    Комментировать
  • Как типизировать динамическое значение?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    export interface ICustomTableCellProps {
      contact: IUser;
      cellData: keyof IUser;
      onChange: Function;
    }

    Должны приходить строка или число (name, lastname, age, pager)

    Не понял, откуда тут число? Если вы используете это так contact[cellData], то cellData очевидно может принимать только значения ключей contact, а contact - это IUser...
    Ответ написан
    3 комментария
  • Как убрать повторяющиеся цифры (судоку)?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Абстракный вопрос, ответ зависит от твоего алгоритма и что тебе вообще надо.
    По хорошему тебе нужно просто не гененровать повторяющиеся числа изначально, а не убирать их постфактум.
    Ответ написан
    Комментировать