Задать вопрос
Ответы пользователя по тегу TypeScript
  • TypeScript. Как собрать объект из массива строк?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    На самом деле чтоб была полноценная типизация надо как-то так:
    getStyles<T extends keyof CSSStyleDeclaration>(styles: readonly T[]) {
      return styles.reduce((res, style) => {
        res[style] = this.$nativeElement.style[style];
        return res;
      }, {} as Pick<CSSStyleDeclaration, T>);
    }

    Песочница.

    Разница с решением от Дмитрий в том, что тип получившегося объекта будет содержать только полученные ключи, а не все возможные в CSSStyleDeclaration.
    Ответ написан
    2 комментария
  • Почему Electronjs не видит экспорты после начала работы?

    Aetae
    @Aetae Куратор тега JavaScript
    Тлен
    Пальцем в небо: попробуй в tsconfig module: esnext.
    Ответ написан
    Комментировать
  • Как работает конструкция type t = {...}[keyof T]?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Обычное обращение по ключу, как в javascript, что тут непонятного?
    const foo = {
      bar: 1
    };
    foo['bar'] // 1
    const baz = {
      qux: 2
    }['qux']; // 2
    тайпскрит в работе с типами тут ничем не отличается:
    type user = {
        id: number,
        name: string,
    };
    type id = user['id']; // number
    type userKeys = keyof user; // 'id' | 'name'
    type userTypes = user[keyof user]; // number | string
    тип never же просто не учитывается:
    number | string | never - то же самое что number | string.
    Ответ написан
    1 комментарий
  • Можно ли задать значение по умолчанию для функции, которая зависит от двух типов дженерика?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Есть такия конструкция: foo as unknown as Type - двойным кастованием вы можете скастовать что угодно во что угодно.
    Только вот делать так не надо, эту убивает весь смысл использования TypeScript.
    Вместо этого вам надо прописать условия в "функции по умолчанию", чтоб она работала так, как это описано, а не хрен пойми как.
    Ответ написан
    6 комментариев
  • Как побороть 431-ю ошибку в nuxt-приложении?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Чтоб передать аргументы командной строки в node можно просто проставить переменную окружения NODE_OPTIONS.

    Но правильное решение - не увеличивать лимиты, а разбираться какого хрена у вас так разжирнел заголовок. Толстый заголовок - мусорный трафик - замедление работы.
    Рекламные сети не должны ничего особо писать в ваши куки и utm-параметры вообще не должны летать внутри вашего сайта.
    Берите дамп запроса(из консоли или с сайта) и смотрите что там за мусор, откуда он взялся и как настроить виновника так, чтоб он этот мусор туда не пихал.
    Ответ написан
    1 комментарий
  • Typescript generic function. How use with other types?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Нет, проблем тут куча.

    T extends [], K extends keyof T - K тут что-то производное от number, потому что ключи(keyof) массива([]) - только цифры.
    let resultSort: T = arr; - бессмысленно, так как arr.sort в любом случае меняет исходный массив.
    a[propertyName].toLowerCase() - упадёт если propertyName будет year, т.к. Number не имеет метода toLowerCase.
    ...

    В итоге функция должна выглядеть как-то так:
    function sortArray<T extends {[key: string]: unknown}, K extends keyof T>  (originArr: T[], propertyName: K, cb: (a: T[]) => T[]): T[] {
      let arr: T[] = JSON.parse(JSON.stringify(originArr));  //deep copy array
    
      arr.sort((a, b) => {
        let nameA = String(a[propertyName]).toLowerCase(),
            nameB = String(b[propertyName]).toLowerCase();
    
        if (nameA < nameB)
          return -1;
        if (nameA > nameB)
          return 1;
        return 0;
      });
    
      return cb(arr);
    }


    Можно не приводить строго к String, но тогда вместо unknown надо указать конкретные типы с которыми предполагается работать, и в самой функции сортировки их учесть.
    Ответ написан
    2 комментария
  • Как должен выглядеть объект при пересечении типов?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Напрямую такой тип задать нельзя. Можно вывести тип, использую функцию-прокладку.
    Ответ написан
    Комментировать
  • Как создать простейший пакет npm на typescript для проекта на cordova (ionic)?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Суть какбэ в том, что в npm должен быть javascript. От ts там остаются только декларации. Потому сборка.
    Физически ты можешь сбацать чисто ts пакет (где module и\или main указывают на .ts файл), но проблема тут в том, что у каждого своя версия ts, а также настройки ts-транспилятора и линтера свои, из-за чего у рандомного юзера нихрена не соберёся.
    Если ты делаешь чисто для себя, то такой проблемы не будет. Поначалу. А потом зоопарк обязательно разрастётся и ты всё проклянешь.
    Но в целом, прямо сейчас, тебе ничего не мешает просто сообрать ts файлики в папочку, добавить соответствующий package.json и получить нужный пакет без лишних телодвижений.)

    Простейшая же сборка: tsc -d --outDir ./dist и package.json, смотрящий на результат.
    Ответ написан
    2 комментария
  • Как разбить большой файл angular на много файлов, при этом оставаясь в одном классе?

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

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Нельзя, увы. На github'е много просьб это запилить, но пока(v3.8) надежды не много.
    Если походить там по перекрёстным ссылкам, можно найти разные (некрасивые) workaround для конкретных случаев, но вот прямо как вы хотите - не получится.
    Ответ написан
  • Как типизировать этот объект?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Как есть, так и типизируй.

    Как минимум:
    state.books.filter((book: { id: string }) => book.id !== id)
    А лучше:
    interface Book {
      id: string;
      // ...
    }
    state.books.filter((book: Book) => book.id !== id)
    А ещё лучше:
    interface Book {
      id: string;
      // ...
    }
    interface State {
      books: Book[];
      // ...
    }
    const state: State = ...
    
    state.books.filter(book => book.id !== id)
    Ответ написан
    Комментировать
  • Как перестать загрязнять код импортом интерфейсов?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Можно просто положить где-то(во включённой в tsconfig.json) директории какой-нить global.d.ts и просто накидать туда часто используемых интерфейсов. )
    Но, конечно, если интерфейсы связанны с какими-то модулями, правильно и хранить их в соответствующих модулях. Всё равно же используя модуль, вы оный импортируете, добавка к импорту ещё и интерфейса погоды не делает.
    Ответ написан
    Комментировать
  • Как правильно добавить новое публичное поле в класс на TypeScript?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Ну или просто проверять что класс пришёл именно тот что надо.)
    class Main {
        constructor(public name: string) {}
    }
    
    class Sub extends Main {
        constructor(name: string, public lastname: string) {
            super(name)
        }
    }
    
    const sub = new Sub('michael', 'jackson')
    
    function hello (person: Main) {
        console.log(person.name)
        if(person instanceof Sub) {
            console.log(person.lastname)
        }
    }
    
    hello(sub)
    Ответ написан
    Комментировать
  • Как сделать чтобы другие параметры были не обязательны?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Мы же говорим о typescript?
    function test (a: number, b?: number, c?: number) {
      console.log(a);
      if (b) console.log(b);
      if (c) console.log(c);
    }
    
    test(1) // консоль: 1
    test(1, 2) // консоль: 1, 2
    Ответ написан
    Комментировать
  • Как исправить ошибку Element implicitly has an 'any'?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    interface Dictionary<T> {
      [key: string]: T
    }
    
    function serialize<T extends Dictionary<string | number[]>> (arg: T) {
      var res = '';
    
      var replaceNamePop: Dictionary<string> = {
        modules: 'module',
        categories: 'category',
        searchFieldsList: 'searchFieldList'
      };
    
      Object.keys(arg).forEach(function (this: T, key) {
        if (Array.isArray(this[key])) {
          for (var j = 0; j < this[key].length; j++) {
            if (typeof replaceNamePop[key] != 'undefined')
              res += '&' + replaceNamePop[key] + '=' + this[key][j];
            else
              res += '&' + key + '=' + this[key][j];
          }
        } else {
          if (typeof replaceNamePop[key] != 'undefined')
            res += '&' + replaceNamePop[key] + '=' + this[key];
          else
            res += '&' + key + '=' + this[key];
        }
      }, arg);
      return res;
    }
    
    serialize({
      'modules': [20],
      'categories': [20],
      'keyword': 'keyword',
      'time': 'time',
      'catRelation': 'cat',
      'sortField': 'sort',
      'sortDirection': 'ASC',
      'searchFieldsList': 'list'
    });
    serialize({
      'modules': [20, 25],
      'categories': [20, 58],
      'keyword': 'keyword',
      'time': 'time',
      'catRelation': 'cat',
      'sortField': 'sort',
      'sortDirection': 'ASC',
      'searchFieldsList': 'list'
    });
    serialize({
      'modules': [20, 25],
      'keyword': 'keyword'
    });
    Ответ написан
    Комментировать
  • Property does not exist on type {}?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    interface User {
      name?: string;
    }
    
    let user: User = {};
    или
    interface User {
      name: string;
    }
    
    let user = {} as User;
    Ответ написан
    Комментировать
  • Как правильно инсталировать mapbox-gl-directions?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    А её нет, этой вашей декларации! *криповый смех*

    Создатели этого модуля не потрудились сделать декларацию, те декларации что в @types поддерживаются сообществом на открытой основе(лежат вот тут), и туда тоже (пока?) никакой самаритянин не добавил ничего.
    Так что вам остаётся только только сделать декларацию самому. Поможет вам в этом (при некоторой удаче) dts-gen.
    Ответ написан
    Комментировать
  • Как заставить правильно компилировать readonly свойство класса?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    А зачем тебе? Какая у тебя есть для того железобетонная причина?
    А так, ты всегда можешь добавить в цепочку сборки собственноручно написанный loader который выполнит любые нужные тебе преобразования.
    Ответ написан
  • React-typescript cannot find module "typescript"? Почему?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Это грустные реалии typescript. При сборке вебпаком всё соберётся нормально, а вот для того чтобы IDE такое скушала - нужна персональна декларация(.d.ts) на каждый sass файл или общая но не информативная вида:
    declare module '*.scss' {
      const scss: any;
      export default scss
    }
    , чтоб он знал какие там где типы.

    Можно для автоматизации использовать такие штуки, но это всё такие костыли...
    Ответ написан
  • Как правильно использовать паттерн проектирования стратегия?

    Aetae
    @Aetae Куратор тега TypeScript
    Тлен
    Если не хотите просто передавать сам класс стратегии как параметр, то остаётся только сделать жэшмапу где ключём будет имя параметра, а значением собсно класс стратегии. При добавлении новой стратегии - добавляеете её же в мапу. Условно как-то так:
    class FormBuilder {
        public static strategies: { [key: string]: {new(): IFormStrategy} } = {
            simple: SimpleFormStrategy,
            extended: ExtendedFormStrategy,
        };
        public build(params: { strategy: string }): Form {
            let strategy: IFormStrategy = new FormBuilder.strategies[params.strategy]();
            return strategy.execute(params);
        }
    }
    
    FormBuilder.strategies.custom = CustomFormStrategy;
    
    const formBuilder = new FormBuilder();
    formBuilder.build({ strategy: 'custosm' });

    Естесно мапу можно сделать приватной и добавление осуществлять публичным методом. Или хранить вообще отдельно. Нужны также проверки что такая стратегия вообще есть, но это всё уже детали...
    Ответ написан
    2 комментария