Làm thế nào để sử dụng Object.values ​​với bản thảo?


135

Tôi đang cố gắng tạo thành một chuỗi được phân tách bằng dấu phẩy từ một đối tượng,

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

Làm thế nào để làm điều này với TypeScript?

nhận được một tập tin lỗi:

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

Câu trả lời:


106

sử dụng Object.keys thay thế.

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

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

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

90
Lưu ý rằng đây là một giải pháp thay thế (một câu trả lời hay!), Không phải là câu trả lời thực tế về cách sử dụng ES7 Object.valuestrong TS để giải quyết lỗi biên dịch của OP. Để làm điều đó bạn chỉ cần ES2017trong --libthiết lập của bạn .
Aaron Beall

4
@Aaron giải pháp của bạn phức tạp đến mức bất kỳ ai mới sử dụng bản thảo đều không thể chấp nhận, để biên dịch bạn phải thêm ES2017lib và phải bao gồm thư viện polyfills trong đó sử dụng câu trả lời khác nhau chống lại những người khác nhau là vua.
holi-java

9
@ holi-jave Đây không phải là "giải pháp của tôi" mà chỉ là cách các tính năng của TS và phi tiêu chuẩn hoạt động, giống như cách sử dụng của OP ES7/Object.values(). Có thể bạn nghĩ nó phức tạp (tôi không đồng ý), nhưng đó chỉ là bản chất của việc cố gắng sử dụng các tính năng trong tương lai như Object.values()ngày nay. Nó luôn luôn là như vậy. Thậm chí Object.keys()vẫn nên được thực hiện đầy đủ nếu bạn đang nhắm mục tiêu ES3 hoặc muốn hỗ trợ IE8 (hy vọng bạn không còn nữa!) Nói chung là nên hiểu các tính năng ES, hỗ trợ trình duyệt và polyfilling nếu bạn đang phát triển web!
Aaron Beall

@Aaron Tôi không nói nó phức tạp, nhưng đối với ai đó mới sử dụng typcript / javascript thì phức tạp hơn và không được chấp nhận.
holi-java


223

Object.values()một phần của ES2017 và lỗi biên dịch bạn gặp phải là do bạn cần định cấu hình TS để sử dụng thư viện ES2017. Bạn có thể đang sử dụng thư viện ES6 hoặc ES5 trong cấu hình TS hiện tại của bạn.

Giải pháp: sử dụng es2017hoặc es2017.objecttrong --libtùy chọn trình biên dịch của bạn .

Ví dụ tsconfig.json: sử dụng :

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

Lưu ý rằng nhắm mục tiêu ES2017 với nguyên cảo không không phát ra polyfills trong trình duyệt cho ES2017 (nghĩa là phá được ở trên bạn biên dịch lỗi, nhưng bạn vẫn có thể gặp phải một thời gian chạy lỗi vì trình duyệt không thực hiện ES2017 Object.values), đó là tùy thuộc vào bạn để polyfill dự án của bạn mã cho mình nếu bạn muốn. Và vì Object.valueschưa được hỗ trợ tốt bởi tất cả các trình duyệt (tại thời điểm viết bài này), bạn chắc chắn muốn một polyfill: core-jssẽ thực hiện công việc .


1
@ErikvanVelzen Bạn đã chỉnh sửa câu trả lời để thay đổi trường hợp ES2017thành es2017nhưng AFAIK đây không phải là cần thiết, nhưng tôi luôn muốn tìm hiểu, có lý do cho sự thay đổi không?
Aaron Beall

2
^ Để trả lời câu hỏi của riêng tôi: ES2017, DOM(chữ hoa) được liệt kê trong các tsc --initbình luận như các giá trị hợp lệ và nó hoạt động một cách chính xác trong trình biên dịch, nhưng schema JSON chỉ liệt kê các es2017, dom(chữ thường) tùy chọn, vì vậy JSON IDE / Linter chí cờ ES2017, DOMnhư một giá trị không hợp lệ (mặc dù chúng hợp lệ). Một chút bối rối.
Aaron Beall

Quả thực đó là lý do. Nó không hoạt động chữ hoa như bạn lưu ý. tsc --helphiển thị chữ thường mặc dù
Erik van Velzen

Không phải core-js được bao gồm trong góc, nếu không đó là cách thêm pollyfill này?
Samiullah Khan

1
@ Totty.js Các tệp thư viện mà TS bao gồm chỉ dành cho kiểm tra kiểu , nói cách khác, nó không thực sự phát ra bất kỳ polyfill thư viện JS nào cho những thứ như Object.values(). Nói cách khác, bạn có thể khắc phục lỗi biên dịch nhưng vẫn gặp lỗi trong thời gian chạy nếu bạn chạy trong trình duyệt không có Object.values().
Aaron Beall

18

Bạn có thể sử dụng Object.valuestrong TypeScript bằng cách này (<any>Object).values(data)nếu vì lý do nào đó bạn không thể cập nhật lên ES7 trong tsconfig.


4
@Aaron tại thời điểm đăng bài đã có những bình luận cho thấy những người sử dụng một phiên bản cụ thể của Angular có vấn đề khi cập nhật lib khi nó không hoạt động. Đó là lý do tại sao tôi đặtif for some reason you can't update to ES7 in tsconfig
mtpultz

11

Thay vì

Object.values(myObject);

sử dụng

Object["values"](myObject);

Trong trường hợp ví dụ của bạn:

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

Điều này sẽ ẩn lỗi trình biên dịch ts.


1
bạn là thiên tài (^ - ') b
harufumi.abe

Phần tử ngầm có loại 'bất kỳ' vì loại 'ObjectConstructor' không có chữ ký chỉ
mục.ts

6
Đây là hành vi sử dụng sai mục đích của TS. Bạn nên cấu hình trình biên dịch với libcài đặt để phản ánh cách bạn đang sử dụng nó, không cố tình thoát khỏi trình biên dịch.
Aaron Beall

1
@AaronBeall đó là một cách sử dụng tốt nếu vì lý do nào đó bạn không thể nâng cấp lên es2017
Dino

@Dino Bạn không cần nâng cấp lên es2017, bạn có thể sử dụng core-js để polyfill hoàn toàn xuống ES5. TypeScript không có thời gian chạy, libcài đặt chỉ để kiểm tra kiểu chính xác.
Aaron Beall

11

Tôi đã tăng mục tiêu trong tôi tsconfig.jsonđể kích hoạt tính năng này trong TypeScript

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

Thay đổi mục tiêu không phải là một giải pháp trong trường hợp bạn muốn giữ khả năng tương thích với các trình duyệt cũ hơn. Bản đánh máy phải có khả năng phiên dịch cú pháp ES2017 sang ES2015.
Ngẫu nhiên

4

Tôi vừa gặp vấn đề chính xác này với Angular 6 bằng cách sử dụng CLI và không gian làm việc để tạo thư viện bằng cách sử dụng ng g library foo.

Trong trường hợp của tôi, vấn đề nằm tsconfig.lib.jsonở thư mục thư viện không có es2017trong libphần này.

Bất cứ ai cũng vấp phải vấn đề này với Angular 6, bạn chỉ cần đảm bảo rằng bạn cập nhật cho bạn tsconfig.lib.jsoncũng như ứng dụng của bạntsconfig.json


Tôi đã đặt es2017 trong cả tsconfig.lib và tsconfig.json, nhưng tôi vẫn nhận được lỗi 'các mục không tồn tại trên lỗi Object' khi cố gắng sử dụng các mục. Có điều gì khác tôi nên thay đổi / cập nhật?
Maurice

tôi đã thay đổi mục tiêu trong tsconfig.lib thành es2017 ngay bây giờ, vẫn cùng một lỗi.
Maurice

2

tslintcấu hình quy tắc của tôi ở đây luôn luôn thay thế dòng Object["values"](myObject)với Object.values(myObject).

Hai tùy chọn nếu bạn có cùng một vấn đề:

(Object as any).values(myObject)

hoặc là

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

1
Tại sao bạn muốn sử dụng Object["values"]?
Aaron Beall

-4

Cách đơn giản nhất là bỏ Objectqua any, như thế này:

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

Và voila - không có lỗi biên dịch;)


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.