• Почему не работают функции на js?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Вы считали значения с полей 1 раз на старте программы, а нужно читать на каждое нажатие кнопки
    Ответ написан
    2 комментария
  • Как поменять формат даты в moment.js?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    const date = '25.10.2020';
    const reformatedDate = moment(date, 'DD.MM.YYYY').format('YYYY-MM-DD');
    Ответ написан
    Комментировать
  • Почему есть разница в названиях свойств объекта Promise?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Потому-что это не свойства, это лишь вьюшки для консоли на внутреннее состояние встроенного в движок JS объекта.
    Каждая реализация вольна называть их по своему, либо вообще не показывать.
    Ответ написан
    Комментировать
  • Зачем нужны Module и Namespace?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    TypeScript появился еще до того, как в JavaScript, на котором он основан, появились какие либо модули, не то что нативные, даже эмуляций вроде commonjs или amd тогда еще не было. В те времена было в норме просто обернуть содержимое файла в замыкание, а потом либо просто подгрузить все файлы через тэг script либо просто соединить эти файлы в один. Наружу же высвечивалась одна единственная переменная, содержащая все публичное апи такого модуля, ее ложили или в глобальный объект или в другую такую-же переменную.
    Конструкции module и namespace позволяют упростить создание таких переменных, избавив разработчика от написания однотипного кода. В этом плане они по сути делают одно и то же.
    Сейчас это не рекомендованное использование, и стандартный плагин typescript к eslint с настройками по умолчанию запрещает эти конструкции.

    Второе применение - это файлы деклараций.
    namespace позволяет объявить объект, но несколько особенный в рамках типизации, он может содержать в себе любые сущности языка и экспортировать не которые из них, в том числе типы, что недоступно для декларации обычного объектного типа.
    declare namespace XXX {
      // по сути просто поле XXX.a
      let a: number;
      // то же поле XXX.b но уже const
      // современный ts позволяет делать поля readonly, но раньше так было нельзя
      const b: number;
      // функция, по сути метод XXX.c()
      function c(): void;
      // а вот вложенный тип через тип объекта не объявить, а в namespace можно
      type T = number | string;
    }

    module позволяют объявить виртуальные модули, о типах которых typescript не знает, например потому что они генерируются сборщиками вроде webpack. Яркий пример тут это css-модули или картинки, которые можно импортировать благодаря webpack, но typescript ничего не знает о их типах, поэтому нужно объявить их в глобальных декларациях:
    declare module '*.png' {
      const url: string;
      export default url;
    }
    declare module '*.css' {
      const classNames: Record<string, string>;
      export default classNames;
    }
    Ответ написан
    1 комментарий
  • Как правильно прописать тип number|null?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    Интерфейс в TypeScript может иметь несколько объявлений в коде, и TypeScript объединит их все в один общий тип. Судя по ошибке с Вашим ApplicationInit именно это произошло, помимо поля initialPayment объявлены другие поля в другом объявлении, поэтому он их и требует.
    Ответ написан
    Комментировать
  • Как развернуть юнион в интерфейс?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    type Union = 'a' | 'b' | 'c';
    type Obj = {
      [K in Union]: any;
    };
    Интерфейсом насколько помню так нельзя
    Ответ написан
  • Что означает этот синтаксис?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Очень похоже на код сжатый через terser.js или что-то подобное.
    Если развернуть немного, то получится вот так:
    let a;
    t >>>= 0;
    if(t < 128) a = 1;
    else if(t < 16384) a = 2;
    else if(t < 2097152) a = 3;
    else if(t < 268435456) a = 4;
    else a = 5;
    this.tail.next = new f(a, t);
    this.tail = this.tail.next;
    this.len += this.tail.len;
    return this;

    Ну а на оператор запятая Вадим уже дал ссылку
    Ответ написан
    Комментировать
  • Нужен ли TypeScript для написания бэкенда на Node.js?

    bingo347
    @bingo347 Куратор тега Node.js
    Crazy on performance...
    Можно ли обойтись обычным js?
    Можно. TypeScript лишь добавляет к JavaScript статическую типизацию в компайл-тайм. После компиляции будет все тот же JS.

    Какие будут плюсы?
    Главный плюс, ИМХО, - скорость разработки за счет подсказок IDE и автодополнения, больше авторефакторингов. Ну и возможность ограничить использование функций/методов от нежелательного использования тоже плюс. А если еще и проектировать доменную модель на типах, то можно сразу видеть, если что-то не сходится, еще до написания логики.

    Не будет ли много лишней писанины по сравнению с чистым js?
    Большинство типов TypeScript способен вывести. Далеко не Хиндли-Милнер конечно, но тоже хорошо. Я пишу больше в ФП стиле, с редкой примесью структурно-процедурного при описании эффектов, так у меня явные указания типов присутствуют только в сигнатурах функций. В самой логике код неотличим от обычного JS, но с хорошей проверкой типов.

    Будет ли сложно хранить скомпилированный js?
    Как и любые другие артефакты сборки, скомпилированный JS хранить не нужно. Компилируйте непосредственно перед выкладыванием на продакшен, а в git храните лишь TS код + настройки компилятора. А в dev среде вообще можно запускаться через модуль ts-node.
    Ответ написан
    Комментировать
  • Проверка значений массива?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    type Validator<U extends string, A extends ReadonlyArray<string>> =
      (U extends A[number] ? true : false) extends true ? A : never;
      
    type U = 'foo' | 'bar';
    const arr0 = ['foo'] as const;
    const arr1 = ['bar'] as const;
    const arr2 = ['foo', 'bar'] as const;
    
    type A0 = Validator<U, typeof arr0>; // never
    type A1 = Validator<U, typeof arr1>; // never
    type A2 = Validator<U, typeof arr2>; // readonly ['foo', 'bar']
    
    const _check0: A0 = arr0; // error
    const _check1: A1 = arr1; // error
    const _check2: A2 = arr2;

    https://www.typescriptlang.org/play?#code/C4TwDgpg...
    Ответ написан
    Комментировать
  • Как забрать данные из промиса?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Нет, это не промис, это асинхронная функция, которая отдает свой результат в колбэк, как правило такая функция ничего не возвращает, а значит и await'ить нечего, так как await требует метод then у результата выражения справа.
    Но можно это обернуть в промис:
    async function checkUser(login, password) {
        const ad = new ActiveDirectory(ad_config)
        const auth = await new Promise((resolve, reject) => {
            ad.authenticate(login, password, (err, auth) => {
                if (err) {
                    return reject(err)
                }
                resolve(auth)
            })
        })
        return auth
    }
    Ответ написан
    1 комментарий
  • Типизация функции, возвращающей разные объекты?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    const elementSettings = {
      welcome: {
        placeholder: 'Type welcome message...',
        question: '',
        isDescription: false,
        description: '',
        startButtonText: 'Start',
      },
      checkbox: {
        placeholder: 'Type question or statement...',
        question: '',
        isDescription: false,
        description: '',
        options: [] as string[],
        multiple: false,
      }, 
      dropdown: {
        placeholder: 'Type question here...',
        question: '',
        isDescription: false,
        description: '',
        options: [] as string[],
      },
      rating: {
        placeholder: 'Type question...',
        question: '',
        isDescription: false,
        description: '',
        steps: 10,
        defaultRate: 0,
        shape: 'stars',
      },
      text: {
        placeholder: 'Type question...',
        question: '',
        isDescription: false,
        description: '',
        maxLength: 99999,
      }, 
      slider: {
        placeholder: 'Type question...',
        question: '',
        isDescription: false,
        description: '',
        steps: 10,
      }, 
      thanks: {
        placeholder: 'Type message...',
        question: '',
        isDescription: false,
        description: '',
      }
    } as const;
    
    type Editable<T> = { -readonly [P in keyof T]: T[P]; };
    type ElementSettings = typeof elementSettings;
    
    export function getElementSettings<T extends keyof ElementSettings>(type: T): Editable<ElementSettings[T]> {
      if(type in elementSettings) {
        const settings = {...elementSettings[type]};
        if('options' in settings) {
          (settings as {options: string[]}).options = (settings as {options: string[]}).options.slice();
        }
        return settings;
      }
      throw new Error("element type doesn't match!");
    }
    Ответ написан
    Комментировать
  • Как задать дженерик для массива в объекте?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    mport React from 'react';
    import { render } from 'react-dom';
    
    type ITableColumn<D extends Record<string, any>> = {
      property: string;
      format?: (value: any, item: D) => React.ReactNode | string | number;
      header?: any;
      footer?: any;
    };
    
    type ITable<T extends Record<string, any>, D extends Record<string, any>> = {
      isLoading?: boolean;
      columns: ITableColumn<D>[];
      rows: Array<T>;
    };
    
    type IContext<D extends Record<string, any>> = {
      rows: any;
      columns: ITableColumn<D>[];
    };
    
    const getColumns = <D extends Record<string, any>>(): ITableColumn<D>[] => [
      {
        property: 'name',
        format: (value, item) => {
          const { lastName } = item;
          return `${value} ${lastName}`;
        },
        header: 'heade',
        footer: 'footer'
      },
      {
        property: 'count',
        header: 'heade',
        footer: 'footer'
      }
    ]
    
    interface AppProps { }
    interface AppState {
      name: string;
    }
    
    const Table:React.FC<ITable> = ({ isLoading, columns, rows }) => {
      return <h1>table</h1>
    }
    
    const App = () => (
      <div>
        <Table 
          columns={getColumns()} 
          rows={[
            { name: 'userName 0', lastName: 'userLastName 0', count: 10 },
            { name: 'userName 1', lastName: 'userLastName 1', count: 20 },
            { name: 'userName 2', lastName: 'userLastName 2', count: 30 },
          ]} 
        />
        <p>Start editing to see some magic happen :)</p>
      </div>
    );
    
    render(<App />, document.getElementById('root'));
    Ответ написан
    2 комментария
  • Как получить все пропсы компонента React по его экземпляру?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    import type {ComponentType} from 'react';
    import {Button} from 'react-native';
    
    type InferProps<Component> = Component extends ComponentType<infer Props> ? Props : never;
    
    const MyButton = (props: InferProps<typeof Button>) => {
      return <Button title={props.title} onPress={props.onPress} style={{color:'#fff'}} />
    }
    Ответ написан
    Комментировать
  • Как из элементов массива сделать type в typescript?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    const arr = ['a', 'b', 'c'] as const;
    type MyType = (typeof arr)[number];
    Ответ написан
    1 комментарий
  • Функция возвращающая данные полученные из БД, как правильно написать?

    bingo347
    @bingo347 Куратор тега Node.js
    Crazy on performance...
    const select = (query) => new Promise((resolve, reject) => {
      const request = new Request(query);
      request.once('error', reject);
      request.once('done', (rowCount, more, rows) => {
        resolve(rows.map(
          columns => columns.map(
            column => column.value
          )
        ));
      });
      connection.execSql(request);
    });
    Ответ написан
    4 комментария
  • Как отправлять сразу несколько запросов в JavaScript?

    bingo347
    @bingo347 Куратор тега JavaScript
    Crazy on performance...
    Подойдет ли тут многопоточность или я что то путаю?
    В JS нет многопоточности.
    Как это реализовать? С помощью чего?
    Просто отправить несколько запросов сразу. Запросы работают асинхронно и не блокируют поток выполнения.
    Если нужно дождаться сразу несколько ответов, есть Promise.all и Promise.allSettled

    P.S. зачем тащить в приложение тяжелый и ограничивающий функционал axios, когда есть нативный fetch?
    Ответ написан
  • Как мне добавить этот код в header и использовать в другом коде?

    bingo347
    @bingo347
    Crazy on performance...
    Давайте по порядку.
    В представленном примере у нас реализация функции, которая не принимает параметров и возвращает указатель на структуру android_app

    struct android_app * - это возвращаемый функцией тип;
    GetAndroidApp - имя функции;
    Конструкция (void) после имени означает, что функция без аргументов, современные компиляторы позволяют писать просто пустые скобки ();
    В фигурных скобках пишут тело функции, то есть ее реализацию.

    Компиляторы C читают код сверху вниз, использовать можно только то, что объявлено выше. Кроме того некоторые сущности вообще могут компилироваться отдельно и уже после линковаться в 1 исполняемый файл.
    Для этого язык C поддерживает декларации сущностей без их реализации, при условии, что сущность будет реализована ниже или где-то еще, что прилинкуется на сборке.
    Для функций декларацией (так же говорят заголовком) является описание ее сигнатуры, то есть для GetAndroidApp таким заголовком будет:
    // описание структуры android_app должно быть выше заголовка его использующего,
    // иначе он будет невалидным. А вот описание полей (реализация) может быть и ниже
    struct android_app;
    
    struct android_app* GetAndroidApp();


    комментарии говорится что я могу добавить его в Header
    Это значит, что данные сигнатуры можно вынести в заголовочный файл (тот что с расширением .h), это позволит вставить его во множество исходников через директиву препроцессора #include
    Ответ написан
    1 комментарий
  • Как сделать постоянный фоновый Process в C#?

    bingo347
    @bingo347
    Crazy on performance...
    Потому что метод ReadToEnd блокирует тред пока не прочитает весь стрим до конца
    Используйте ReadLineAsync или ReadToEndAsync чтоб читать данные асинхронно.
    Ответ написан
    22 комментария
  • Почему я получаю ошибку TS2322?

    bingo347
    @bingo347 Куратор тега TypeScript
    Crazy on performance...
    routes.map((route: IPrivateRoute | IRoute) => route.access // Здесь ошибка, так как в IRoute нет поля access, а значит нет и в юнионе IPrivateRoute | IRoute
      ? <PrivateRoute key={route.path} {...route}/> // а здесь, так как route.access не является тайп-гвардом, и не смотря на условие, тип по прежнему IPrivateRoute | IRoute
    Ответ написан
    Комментировать