Bagaimana cara menggunakan Object.values ​​dengan skrip ketikan?

137

Saya mencoba membentuk string yang dipisahkan koma dari suatu objek,

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);

Bagaimana melakukan ini dengan TypeScript?

mendapatkan file kesalahan:

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

Jawaban:

107

menggunakan Object.keys sebagai gantinya.

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

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

const commaJoinedValues = values.join(",");
console.log(commaJoinedValues);
holi-java
sumber
92
Perhatikan bahwa ini adalah alternatif (yang bagus!), Bukan jawaban sebenarnya tentang cara menggunakan ES7 Object.valuesdi TS untuk menyelesaikan kesalahan kompilasi OP. Untuk melakukan itu, Anda hanya perlu ES2017dalam --libpengaturan Anda .
Aaron Beall
4
@Aaron Solusi Anda sangat kompleks sehingga siapa pun yang baru mengenal skrip ketikan tidak dapat menerima, untuk mengkompilasi Anda harus menambahkan ES2017lib, dan harus menyertakan pustaka polyfills di mana menggunakannya. Berikan jawaban yang berbeda terhadap orang yang berbeda adalah rajanya.
holi-java
9
@ holi-jave Ini bukan "solusi saya", ini hanya bagaimana TS dan fitur JS yang belum standar bekerja, seperti percobaan penggunaan OP ES7/Object.values(). Mungkin Anda berpikir itu rumit (saya tidak setuju), tetapi itu hanya sifat mencoba menggunakan fitur masa depan seperti Object.values()saat ini. Selalu seperti ini. Bahkan Object.keys()masih harus di-polyfill jika Anda menargetkan ES3 atau ingin mendukung IE8 (semoga Anda tidak lagi!). Ide yang baik secara umum untuk memahami fitur ES, dukungan browser, dan polyfilling jika Anda dalam pengembangan web!
Aaron Beall
@Aaron Saya tidak mengatakan itu rumit, tetapi untuk seseorang yang baru mengenal skrip / javascript lebih kompleks dan tidak diterima.
holi-java
1
Mari kita lanjutkan diskusi ini dalam obrolan .
holi-java
231

Object.values()adalah bagian dari ES2017 , dan kesalahan kompilasi yang Anda dapatkan adalah karena Anda perlu mengkonfigurasi TS untuk menggunakan perpustakaan ES2017. Anda mungkin menggunakan pustaka ES6 atau ES5 dalam konfigurasi TS Anda saat ini.

Solusi: gunakan es2017atau es2017.objectdalam --libopsi kompiler Anda .

Misalnya, menggunakan tsconfig.json:

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

Perhatikan bahwa menargetkan ES2017 dengan naskah yang tidak memancarkan polyfills di browser untuk ES2017 (yang berarti memecahkan di atas Anda kompilasi kesalahan, tapi Anda masih bisa menemukan sebuah runtime error karena browser tidak melaksanakan ES2017 Object.values), itu terserah Anda untuk Polyfill proyek Anda kode sendiri jika Anda mau. Dan karena Object.valuesbelum didukung dengan baik oleh semua browser (pada saat tulisan ini dibuat), Anda pasti menginginkan polyfill: core-jsakan melakukan pekerjaan itu .

Aaron Beall
sumber
1
@ErikvanVelzen Anda mengedit jawaban untuk mengubah kasus ES2017menjadi es2017tetapi AFAIK ini tidak perlu, tetapi saya selalu ingin belajar, apakah ada alasan untuk perubahan?
Aaron Beall
2
^ Untuk menjawab pertanyaan saya sendiri: ES2017, DOM(huruf besar) tercantum dalam tsc --initkomentar sebagai nilai yang valid dan bekerja dengan benar di compiler, tetapi JSON skema hanya merinci es2017, dom(huruf kecil) pilihan, sehingga JSON IDE / linter akan bendera ES2017, DOMsebagai nilai yang tidak valid (meskipun valid). Agak membingungkan.
Aaron Beall
Memang itu alasannya. Itu bekerja dengan huruf besar seperti yang Anda catat. tsc --helpmenampilkan huruf kecil meskipun
Erik van Velzen
Bukankah core-js termasuk angular, kalau bukan itu cara menambahkan pollyfill ini?
Samiullah Khan
1
@ Totty.js Berkas pustaka yang disertakan TS hanya untuk pemeriksaan tipe , dengan kata lain ia tidak benar-benar memancarkan polyfill pustaka JS untuk hal-hal seperti Object.values(). Dengan kata lain, Anda bisa mengatasi kesalahan kompilasi tetapi masih mengalami kesalahan runtime jika Anda menjalankan di browser yang tidak memilikinya Object.values().
Aaron Beall
18

Anda dapat menggunakan Object.valuesTypeScript dengan melakukan ini (<any>Object).values(data)jika karena alasan tertentu Anda tidak dapat memperbarui ke ES7 di tsconfig.

mtpultz.dll
sumber
4
@Aaron pada saat memposting ada komentar yang menunjukkan orang-orang yang menggunakan versi tertentu dari Angular mengalami masalah dalam memperbarui lib yang tidak berfungsi. Itulah sebabnya saya menempatkanif for some reason you can't update to ES7 in tsconfig
mtpultz
12

Saya telah meningkatkan target saya tsconfig.jsonuntuk mengaktifkan fitur ini di TypeScript

{
    "compilerOptions": {
        "target": "es2017",
        ......
    }
}
Lukas Ignatavičius
sumber
Mengubah target bukanlah solusi jika Anda ingin menjaga kompatibilitas dengan browser lama. Ketikan harus mampu mentranspilasi sintaks ES2017 ke ES2015.
Acak
11

Dari pada

Object.values(myObject);

menggunakan

Object["values"](myObject);

Dalam contoh kasus Anda:

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

Ini akan menyembunyikan kesalahan kompiler ts.

Kian
sumber
1
Anda jenius (^ - ') b
harufumi.abe
Elemen secara implisit memiliki tipe 'apapun' karena tipe 'ObjectConstructor' tidak memiliki tanda tangan indeks.
TS
6
Ini adalah penggunaan TS yang salah. Anda harus mengonfigurasi kompilator dengan libpengaturan untuk mencerminkan bagaimana Anda menggunakannya, tidak sengaja keluar dari kompilator.
Aaron Beall
1
@AaronBeall itu berguna jika karena alasan tertentu Anda tidak dapat meningkatkan ke es2017
Dino
@Dino Anda tidak perlu mengupgrade ke es2017, Anda dapat menggunakan core-js untuk melakukan polyfill hingga ke ES5. TypeScript tidak memiliki runtime, libpengaturannya hanya untuk mendapatkan pemeriksaan jenis yang benar.
Aaron Beall
4

Saya baru saja mengenai masalah yang tepat ini dengan Angular 6 menggunakan CLI dan ruang kerja untuk membuat perpustakaan menggunakan ng g library foo.

Dalam kasus saya, masalahnya ada di tsconfig.lib.jsonfolder perpustakaan yang tidak es2017disertakan di libbagian tersebut.

Siapa pun yang menemukan masalah ini dengan Angular 6 Anda hanya perlu memastikan bahwa Anda memperbarui Anda tsconfig.lib.jsonserta aplikasi Andatsconfig.json

Neil Stevens
sumber
saya telah meletakkan es2017 di kedua tsconfig.lib dan tsconfig.json, tetapi saya masih mendapatkan kesalahan 'entri tidak ada pada kesalahan Objek' ketika mencoba menggunakan entri. Apakah ada hal lain yang harus saya ubah / perbarui?
Maurice
saya mengubah target di tsconfig.lib ke es2017 sekarang, masih kesalahan yang sama.
Maurice
3

Memiliki tslintkonfigurasi aturan saya di sini selalu mengganti baris Object["values"](myObject)dengan Object.values(myObject).

Dua opsi jika Anda memiliki masalah yang sama:

(Object as any).values(myObject)

atau

/*tslint:disable:no-string-literal*/
`Object["values"](myObject)`
kuncevic.dev
sumber
1
Mengapa Anda ingin menggunakan Object["values"]?
Aaron Beall
-4

Cara termudah adalah dengan mentransmisikan Objectke any, seperti ini:

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);

Dan voila - tidak ada kesalahan kompilasi;)

Maksymilian Majer
sumber