Ответы пользователя по тегу TypeScript
  • Чем отличаются примитивные типы от литеральных?

    @ned4ded
    Верстка, Фронтенд
    Если типу присвоить значение, то оно станет литеральным типом.

    type CarNames = 'bmw' | 'mercedes';
    
    const cars: CarNames[] = ['bmw', 'mercedes', 'zhiguli'];
    //                                            ^^^^^^^ 
    //              TypeError: Type '"zhiguli"' is not assignable to type 'CarNames'.


    подробнее и с примерами в официальной документации.

    Соответственно, отвечая на первый вопрос: литеральный тип - это конкретное значение одного из примитивных типов. Хотя в хэндбуке говорится о литеральных типах только для строк и чисел, можно назвать "литеральным" и значения null, undefined, true, false, но в этом нет особо смысла.
    Ответ написан
    5 комментариев
  • Почему Typescript показывает ошибку?

    @ned4ded
    Верстка, Фронтенд
    Typescript показывает ошибку, потому что он типизирует любые ключи объекта, переданные в Object.keys и Object.entries, как строки (а не строковые константы). Это заложенное поведение. Причину называют разрабы следующую: "объект может иметь больше свойств во время рантайма, поэтому тип string[]" (тред1, тред2).

    Доступ к свойству объекта без ошибки в данном случае можно получить только если задать типизацию самостоятельно.

    Самое простое решение:
    const data: {
        hello: {
            wtf: string;
        };
    } = {
        hello: {
            wtf: 'world',
        },
    };
    
    for (const [key] of Object.entries(data) as [keyof typeof data, any][]) {
        console.log(data[key]); 
    }


    Читабельность такого кода, конечно, сильно страдает. Более подходящий вариант:
    interface Data {
        hello: {
            wtf: string;
        };
    }
    
    type DataKey = keyof Data;
    
    const data: Data = {
        hello: {
            wtf: 'world',
        },
    };
    
    for (const [key] of Object.entries(data) as [DataKey, any][]) {
        console.log(data[key]);
    }
    Ответ написан
    Комментировать
  • Как собрать шаблон под React + Typescript?

    @ned4ded
    Верстка, Фронтенд
    У вас не установлен лоадер для typescript.

    Есть 2 варианта, 1ый - ts-loader, 2ой - babel-loader c typescript пресетом.

    Я предпочитаю второй, но в таком случае напрямую бабель не будет производить проверку типов и нужно использовать плагин fork-ts-checker. Проверка типов будет происходить параллельно с процессом компиляции вебпака.

    Вот пример для бабель-лоадера.

    // webpack.config 
    
    module.exports = {
        module: {
            rules: [
                {
                    oneOf: [
                        {
                            test: /\.(js|jsx|ts|tsx)$/,
                            exclude: /(node_modules|bower_components)/,
                            loader: 'babel-loader',
                            options: {
                                cacheDirectory: true,
                            },
                        },
    
                        {
                            use: 'file-loader',
                            exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
                        },
    
                        // ** STOP ** Are you adding a new loader?
                        // Make sure to add the new loader(s) before the "file" loader.
                    ],
                },
            ],
        },
    
        plugins: [
            new ForkTsCheckerWebpackPlugin({
                async: true,
                useTypescriptIncrementalApi: true,
                checkSyntacticErrors: true,
                eslint: true,
            }),
        ],
    };
    
    // babelrc
    
    {
        "presets": [
            "@babel/preset-env",
            "@babel/preset-typescript"
        ],
    }


    Не забудьте установить пресеты, лоадеры и плагин.

    PS, можете подсмотреть конфиг для create-react-app, там можно выудить много интересного.
    Ответ написан
    4 комментария
  • Почему выбивает ошибку в функции?

    @ned4ded
    Верстка, Фронтенд
    Добрый день.

    Метод getItem возвращает либо Products, либо undefined, если продукт не найден. Сделайте терминальное условие и укажите строгую типизация для используемого массива далее.

    addToCart = (id: number) => {
      let tempProduct: Products[] = [...this.state.products];
      const item = this.getItem(id);
      if(item === undefined) {
        // ... инструкция при возникновении терминального условия, например, ошибка
        return;
      }
      const index = tempProduct.indexOf(item as Products); // строгая типизация для item
            
      // ...
    };


    Возможно, если вы укажите тип возвращаемого значения, то не потребуется терминальное условие (но это нужно проверить, я так навскидку не могу утверждать со 100% уверенностью). Такой подход подвержен багам при исполнении js.

    getItem = (id: number): Products => {
      return this.state.products.find(item => item.id === id);
    };


    BTW, я бы не стал называть на вашем месте тип Products во мн. ч. Просто Product, т.к. по сути это единичная сущность.
    Ответ написан
    5 комментариев
  • Компилятор для typescript в вебпаке для реакт проекта, объясните разницу?

    @ned4ded
    Верстка, Фронтенд
    Добрый день.

    Отвечая на ваш вопрос - "Почему в проектах для react частенько используется ts-loader, а не babel-loader?" - они взаимозаменяемы, т.к. оба являются транспайлерами, отличаются только входные данные.

    Отвечая на - "Не проще ли, чтобы все вместе разбирал babel?" - нет, не проще, бабель не производит проверку типов и все равно потребуется установка tsc и, соответственно, настройку вебпака для использования tsc для проверки типов перед сборкой кода через бабель. Несмотря на некоторые соприкасающиеся фичи, typescript является скорее другим языком программирования, тогда как babel берет за основу современные версии ecmascripta. Иными словами, js до компиляции бабелем можно запускать в современных или будущих браузерах, тогда как typescript никогда нельзя будет запускать напрямую в js среде без компиляции. И отсюда возникает вопрос, зачем использовать babel для компиляции синтаксиса typescript'a в js без проверки типов и иных фич tsc, когда у typescript'а есть свой транспайлер? На этот вопрос я предлагаю ответить вам.

    Вот ссылка на реализованные фичи в разных средах.
    Ответ написан
    Комментировать