Свойство 'entries' не существует в типе 'ObjectConstructor'

Я работаю над реализацией ng2. Я использую следующий вызов функции для преобразования объекта в массив:

var authors = Object.entries(responseObject.Authors);

Это стандартная js-функция. Однако компилятор ts возвращает следующую ошибку:

"Property 'entries' does not exist on type 'ObjectConstructor'"

Основываясь на быстром Google, похоже, что решение может заключаться в изменении целевого свойства compilerOptions от es5 до es6. Однако после некоторых предыдущих исследований для предыдущего выпуска я подумал, что мне удалось использовать функциональность es6, включив дополнительное свойство lib на моем tsconfig.json ниже:

  "compilerOptions": {
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "module": "commonjs",
    "noEmitOnError": true,
    "noImplicitAny": false,
    "outDir": "../Scripts/",
    "removeComments": false,
    "sourceMap": true,
    "target": "es5",
    "moduleResolution": "node",
    "lib": [
      "es2015",
      "dom"
    ]
  }

Я также попытался изменить свойство target на es2015, а затем перестроил проект и выполнил "typescriptUsingTsConfig", но я все равно получаю ту же ошибку. Любая идея, что я могу сделать здесь, чтобы использовать функцию Object.entries()?

Ответ 1

Вы совершенно правы, что смена target - это неправильный подход, а смена lib - это правильный подход, однако вы указали неверную версию языка. Согласно MDN, Object.entries был официально добавлен в спецификации ES2017.

"lib": ["es2017"]

поэтому вы должны указать вместо *.

Если вы хотите добавить только объявления для методов функции Object которые были добавлены в ES2017, TypeScript позволяет вам указать более детализированное значение.

"lib": ["es2017.object"]

Как отметил Александр Берд, по умолчанию неявное значение параметра "lib" зависит от значения, указанного для "target" если оно присутствует.

Например:

"target": "es2017"

По умолчанию будет включен соответствующий префикс "lib.*" Если явно не указан "lib".

Обратите внимание, что вы, вероятно, захотите добавить polyfill самой реализации, такой как this, чтобы гарантировать, что это работает в более ранних версиях.

Примечание: в качестве альтернативы вы можете указать любую более позднюю версию

"lib": ["es2018"]

или, естественно, даже

"lib": ["esnext"]

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

Примечание: несколько комментаторов спросили, почему было бы неправильно менять --target вместо --lib как оба позволят коду проверять тип? Причина в том, что --target меняет способ передачи кода. Например, "target": "es2017" означает, что async функции не будут преобразованы для более старых сред выполнения. Это неверно, потому что целью было разрешить использование дополнительных библиотек, а не изменить синтаксис вывода, и поэтому важно различать синтаксические и библиотечные функции.