Як використовувати Object.values ​​з typecript?


135

Я намагаюся сформувати відокремлений комою рядок від об'єкта,

const data = {"Ticket-1.pdf":"8e6e8255-a6e9-4626-9606-4cd255055f71.pdf","Ticket-2.pdf":"106c3613-d976-4331-ab0c-d581576e7ca1.pdf"};
const values = Object.values(data).map(x => x.substr(0, x.length - 4));
const commaJoinedValues = values.join(',');
console.log(commaJoinedValues);

Як це зробити з TypeScript?

отримання файлу помилки:

severity: 'Error'
message: 'Property 'values' does not exist on type 'ObjectConstructor'.'
at: '216,27'
source: 'ts'

Відповіді:


106

використовуючи натомість Object.keys.

const data = {
  a: "first",
  b: "second",
};

const values = Object.keys(data).map(key => data[key]);

const commaJoinedValues = values.join(",");
console.log(commaJoinedValues);

90
Зауважте, що це альтернатива (хороша!), А не фактична відповідь про те, як використовувати ES7 Object.valuesв TS для вирішення помилки компіляції ОП. Для цього вам просто потрібно ES2017в --libналаштуваннях.
Аарон Білл

4
@Aaron ваше рішення настільки складне, що будь-хто, хто не вводить машинопис, не може прийняти, для компіляції ви повинні додати ES2017lib, а також потрібно включати бібліотеку поліфілів, де його використовуйте.
holi-java

9
@ holi-jave Це не "моє рішення", а лише те, як працюють ТС та нестандартні функції JS, як це намагалися використовувати ОП ES7/Object.values(). Можливо, ви вважаєте його складним (я не погоджуюся), але це лише суть спроб використовувати майбутні функції, як Object.values()сьогодні. Це завжди було так. Навіть Object.keys()все-таки слід заповнити, якщо ви орієнтувались на ES3 або хочете підтримувати IE8 (сподіваємось, що ви цього більше не робите!) Загалом, це гарна ідея зрозуміти функції ES, підтримку браузера та поліфілінг, якщо ви працюєте в веб-розробці!
Аарон Білл

@Aaron Я не кажу, що це складно, але для когось нового в typecript / javascript є складнішим і не приймається.
holi-java


224

Object.values()є частиною ES2017 , і помилка компіляції, яку ви отримуєте, полягає в тому, що вам потрібно налаштувати TS для використання бібліотеки ES2017. Напевно ви використовуєте бібліотеку ES6 або ES5 у вашій поточній конфігурації TS.

Рішення: використовуйте es2017або es2017.objectу вашому --libваріанті компілятора .

Наприклад, використовуючи tsconfig.json:

"compilerOptions": {
    "lib": ["es2017", "dom"]
}

Зверніть увагу , що таргетинг ES2017 з машинописом ніяк НЕ випускає polyfills в браузері для ES2017 (маючи у вигляді вище вирішує вашу компіляції помилки, але ви можете зіткнутися під час виконання помилки , тому що браузер не реалізує ES2017 Object.values), це до вас , щоб polyfill вашого проекту код себе, якщо хочете. А так як Object.valuesще не дуже добре підтримується всіма браузерами (на момент написання цієї статті) , ви безумовно хочете polyfill: core-jsбуде робити цю роботу .


1
@ErikvanVelzen Ви редагували відповідь, щоб змінити справу ES2017на, es2017але AFAIK це не обов'язково, але я завжди хочу дізнатися, чи була причина для змін?
Аарон Білл

2
^ Щоб відповісти на мій власний питання: ES2017, DOM( в верхньому регістрі) приведено в tsc --initкоментарі , як допустимі значення і коректно працює в компіляторі, але схема JSON перераховує тільки es2017, domваріанти ( в нижньому регістрі), так що JSON IDE / Лінтера прапор ES2017, DOMа недійсні значення (навіть якщо вони дійсні). Трохи заплутано.
Аарон Білл

Дійсно, це було причиною. Як зазначаєте, він працює з великої літери. tsc --helpВідображається малі регістри
Ерік ван Вельцен

Чи не core-js включений у кутовий, якщо не так, як додати цей pollyfill?
Саміулах Хан

1
@ Totty.js Бібліотечні файли, до складу яких входить TS, призначені лише для перевірки типу , іншими словами, він фактично не випромінює жодних поліфілів бібліотеки JS для таких речей Object.values(). Іншими словами, ви можете обійти помилку компіляції, але все-таки зіткнетеся з помилками виконання, якщо ви працюєте в браузері, який не має Object.values().
Aaron Beall

18

Ви можете використовувати Object.valuesв TypeScript, зробивши це, (<any>Object).values(data)якщо з якоїсь причини ви не можете оновити до ES7 в tsconfig.


4
@Aaron під час публікації з'явилися коментарі, в яких вказувалося на те, що люди, які використовують певну версію Angular, мали проблеми з оновленням lib там, де вона не працювала. Ось чому я поставивif for some reason you can't update to ES7 in tsconfig
mtpultz

11

Замість

Object.values(myObject);

використання

Object["values"](myObject);

У вашому прикладі:

const values = Object["values"](data).map(x => x.substr(0, x.length - 4));

Це приховає помилку компілятора ts.


1
ти геній (^ - ') b
harufumi.abe

Елемент неявно має тип "будь-який", оскільки тип "ObjectConstructor" не має індексу
подпис.ts

6
Це неправильне використання ТС. Ви повинні налаштувати компілятор з libналаштуванням, щоб відображати, як ви його використовуєте, а не навмисно уникати компілятора.
Аарон Білл

1
@AaronBeall це корисно, якщо з якихось причин ви не можете перейти до es2017
Dino

@Dino Вам не потрібно переходити на es2017, ви можете використовувати core-js для поліфаування аж до ES5. У TypeScript немає часу виконання, libналаштування полягає лише в тому, щоб отримати правильну перевірку типу.
Аарон Білл

11

Я збільшив ціль, tsconfig.jsonщоб увімкнути цю функцію в TypeScript

{
    "compilerOptions": {
        "target": "es2017",
        ......
    }
}

Зміна цілі не є рішенням, якщо ви хочете зберегти сумісність зі старими браузерами. Типовий сценарій повинен мати змогу передати синтаксис ES2017 в ES2015.
Випадково

4

Я просто потрапив на цю точну проблему з Angular 6 за допомогою CLI та робочих просторів для створення бібліотеки за допомогою ng g library foo .

У моєму випадку проблема була в tsconfig.lib.jsonпапці бібліотеки, яка не була es2017включена до libрозділу.

Кожен, хто наткнеться на цю проблему з кутовим 6, вам просто потрібно переконатися, що ви оновили tsconfig.lib.json , а також вашу заявкуtsconfig.json


Я поставив es2017 і в tsconfig.lib, і в tsconfig.json, але все ж я отримую помилку "записи не існують на" Об'єкт "помилка при спробі використання записів. Чи є ще щось, що я повинен змінити / оновити?
Моріс

я змінив ціль у tsconfig.lib на es2017 саме зараз, все одно та сама помилка.
Моріс

2

tslintКонфігурація моїх правил завжди замінює рядок Object["values"](myObject)наObject.values(myObject) .

Два варіанти, якщо у вас однакова проблема:

(Object as any).values(myObject)

або

/*tslint:disable:no-string-literal*/
`Object["values"](myObject)`

1
Навіщо вам хотіти використовувати Object["values"]?
Аарон Білл

-4

Найпростіше спосіб кинути ObjectTo any, як це:

const data = {"Ticket-1.pdf":"8e6e8255-a6e9-4626-9606-4cd255055f71.pdf","Ticket-2.pdf":"106c3613-d976-4331-ab0c-d581576e7ca1.pdf"};
const obj = <any>Object;
const values = obj.values(data).map(x => x.substr(0, x.length - 4));
const commaJoinedValues = values.join(',');
console.log(commaJoinedValues);

І вуаля - помилок компіляції немає;)


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.