Có cách nào để có EnScript kiểu tương thích với chuỗi từ JSON không?Các kiểu chữ `enum` từ chuỗi JSON
Ví dụ:
enum Type { NEW, OLD }
interface Thing { type: Type }
let thing:Thing = JSON.parse('{"type": "NEW"}');
alert(thing.type == Type.NEW); // false
tôi sẽ nhưthing.type == Type.NEW
đến mức khó tin. Hoặc cụ thể hơn, tôi muốn tôi có thể chỉ định các giá trị enum
được xác định là chuỗi, không phải số.
Tôi biết rằng tôi có thể sử dụng thing.type.toString() == Type[Type.NEW]
nhưng điều này là cồng kềnh và dường như làm cho chú thích loại enum gây nhầm lẫn và gây nhầm lẫn, đánh bại mục đích của nó. JSON về mặt kỹ thuật là không phải cung cấp giá trị enum hợp lệ, vì vậy tôi không nên nhập thuộc tính vào enum.
Vì vậy, những gì tôi hiện đang làm thay vì đang sử dụng một loại chuỗi với các hằng số tĩnh:
const Type = { NEW: "NEW", OLD: "OLD" }
interface Thing { type: string }
let thing:Thing = JSON.parse('{"type": "NEW"}');
alert(thing.type == Type.NEW); // true
này được tôi sử dụng tôi muốn, nhưng kiểu chú thích string
là cách quá rộng và dễ bị lỗi.
Tôi hơi ngạc nhiên khi một tập hợp siêu nhỏ của JavaScript không có chuỗi dựa trên enums. Tui bỏ lỡ điều gì vậy? Có cách nào khác có thể thực hiện được không?
Update TS 1,8
Sử dụng string literal types là một lựa chọn (nhờ @basaret), nhưng để có được việc sử dụng enum như mong muốn (trên) nó đòi hỏi việc xác định giá trị của bạn hai lần: một lần trong một loại chuỗi ký tự, và một lần dưới dạng một giá trị (hằng số hoặc không gian tên):
type Type = "NEW" | "OLD";
const Type = {
NEW: "NEW" as Type,
OLD: "OLD" as Type
}
interface Thing { type: Type }
let thing:Thing = JSON.parse(`{"type": "NEW"}`);
alert(thing.type === Type.NEW); // true
Điều này hoạt động nhưng tốn rất nhiều công sức, đủ để tôi không sử dụng nó nhiều nhất o f thời gian. Bây giờ tôi hy vọng proposal for string enums
cuối cùng sẽ làm lộ trình.
Update TS 2.1
mới keyof
type lookup phép cho chuỗi loại đen được tạo ra từ các phím của một const hoặc namespace, mà làm cho định nghĩa một dư thừa chút ít:
namespace Type {
export const OLD = "OLD";
export const NEW = "NEW";
}
type Type = keyof typeof Type;
interface Thing { type: Type }
const thing: Thing = JSON.parse('{"type": "NEW"}');
thing.type == Type.NEW // true
Cập nhật T S 2.4
TypeScript 2.4 added support for string enums!Ví dụ trên trở thành:
enum Type {
OLD = "OLD",
NEW = "NEW"
}
interface Thing { type: Type }
const thing: Thing = JSON.parse('{"type": "NEW"}');
alert(thing.type == Type.NEW) // true
này trông gần hoàn hảo, nhưng vẫn có một số đau lòng:
- Bạn vẫn phải viết giá trị gấp đôi, tức là
OLD = "OLD"
, và không có xác nhận rằng bạn không có lỗi đánh máy, nhưNEW = "MEW"
... điều này đã cắn tôi bằng mã thực. Có một số điều kỳ quặc (có thể là lỗi?) Với cách kiểm tra kiểu enum, nó không chỉ là viết tắt kiểu chữ, đó là điều thực sự đúng. Một số vấn đề tôi đã tình cờ gặp:
enum Color { RED = "RED", BLUE = "BLUE", GREEN = "GREEN" } type ColorMap = { [P in Color]: number; } declare const color: Color; declare const map: ColorMap; map[color] // Error: Element implicitly has an 'any' type because type 'ColorMap' has no index signature. const red: Color = "RED"; // Type '"RED"' is not assignable to type 'Color'. const blue: Color = "BLUE" as "RED" | "BLUE" | "GREEN"; // Error: Type '"RED" | "BLUE" | "GREEN"' is not assignable to type 'Color'.
Mã tương đương với
enum Color
thay thế bằng chuỗi loại đen hoạt động tốt ...
Yeah, tôi nghĩ rằng tôi có OCD về vấn đề này, tôi chỉ muốn các enums JS hoàn hảo của tôi. :)
Cảm ơn! Tôi ước gì tôi đã biết về sự khẳng định của 'bất kỳ' trước đây. Bây giờ, tôi đang cố gắng ra TS 2.4 chuỗi enums, và nó khá gần với những gì tôi ban đầu muốn ... nhưng tôi đã tìm thấy một số vấn đề với cách TS loại kiểm tra nó ... – Aaron
@ Aaron mát mẻ, vui mừng để giúp đỡ! Ngoài ra, bạn có thể muốn kiểm tra dự án [ts-enums] (https://github.com/LMFinney/ts-enums) vì nó làm cho việc xử lý enum rất linh hoạt và mạnh mẽ cho nhiều trường hợp sử dụng –