2017-07-03 16 views
6

Tôi muốn sử dụng chuỗi enums trong bản in nhưng tôi không thể thấy hỗ trợ cho ánh xạ đảo ngược trong đó. Tôi có một enum như thế này:Ánh xạ ngược cho chuỗi Enums

enum Mode { 
    Silent = "Silent", 
    Normal = "Normal", 
    Deleted = "Deleted" 
} 

và tôi cần phải sử dụng nó như thế này:

let modeStr: string; 
let mode: Mode = Mode[modeStr]; 

và có tôi không biết là những gì nó có trong modeStr chuỗi và tôi cần nó phân tích cú pháp đến enum hoặc thất bại khi phân tích cú pháp trong thời gian chạy nếu chuỗi không được trình bày trong định nghĩa enum. Tôi có thể làm điều đó gọn gàng như thế nào? cảm ơn trước

+1

Có thể trùng lặp của [Tạo một enum với giá trị chuỗi trong Typescript] (https://stackoverflow.com/questions/15490560/create-an-enum-with-string-values-in-typescript) –

+0

@ ponury-kostek Về mặt kỹ thuật, câu hỏi đó không giải quyết vấn đề lập bản đồ ngược. Ngay cả khi nó có, nó có thể ngồi trong một trong nhiều câu trả lời ẩn ở phía dưới, làm cho các giải pháp quá khó để tìm thấy. Tôi nói nếu không có một bản sao tốt hơn, hãy giữ cái này. –

Trả lời

5

Chúng tôi có thể đặt Mode thành loại và giá trị cùng loại.

type Mode = string; 
let Mode = { 
    Silent: "Silent", 
    Normal: "Normal", 
    Deleted: "Deleted" 
} 

let modeStr: string = "Silent"; 
let mode: Mode; 

mode = Mode[modeStr]; // Silent 
mode = Mode.Normal; // Normal 
mode = "Deleted"; // Deleted 
mode = Mode["unknown"]; // undefined 
mode = "invalid"; // "invalid" 

Một phiên bản chặt chẽ hơn:

type Mode = "Silent" | "Normal" | "Deleted"; 
const Mode = { 
    get Silent(): Mode { return "Silent"; }, 
    get Normal(): Mode { return "Normal"; }, 
    get Deleted(): Mode { return "Deleted"; } 
} 

let modeStr: string = "Silent"; 
let mode: Mode; 

mode = Mode[modeStr]; // Silent 
mode = Mode.Normal; // Normal 
mode = "Deleted"; // Deleted 
mode = Mode["unknown"]; // undefined 
//mode = "invalid"; // Error 

Chuỗi Enum như this answer:

enum Mode { 
    Silent = <any>"Silent", 
    Normal = <any>"Normal", 
    Deleted = <any>"Deleted" 
} 

let modeStr: string = "Silent"; 
let mode: Mode; 

mode = Mode[modeStr]; // Silent 
mode = Mode.Normal; // Normal 
//mode = "Deleted"; // Error 
mode = Mode["unknown"]; // undefined 
+0

Cảm ơn ... Nó có thể đã được thực hiện trong bản đánh máy mặc dù. –

+0

tslint sẽ ném một lỗi trên ví dụ Enum đó: * Phần tử ngầm có loại 'bất kỳ' vì biểu thức chỉ mục không thuộc loại 'số' *. Tôi đoán vấn đề là trong TS chuỗi Enums không thể được ánh xạ ngược lại, xem bình luận trong ví dụ String-Enum tại https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-4 .html - Điều này có vẻ đúng với TS 2.4 nơi String-Enum được giới thiệu nhưng tôi cũng gặp lỗi trong TS 2.6.2 – masi

+0

@masi Kể từ 2.4, TS đã hỗ trợ cho chuỗi enums, vì vậy bạn không cần phải thêm '' truyền. – Rodris

1

Nếu bạn ok với việc sử dụng Proxy, tôi đã chung chung hơn & phiên bản nhỏ gọn:

stringEnum.ts

export type StringEnum<T extends string> = {[K in T]: K} 
const proxy = new Proxy({}, { 
    get(target, property) { 
    return property; 
    } 
}) 
export default function stringEnum<T extends string>(): StringEnum<T> { 
    return proxy as StringEnum<T>; 
} 

Cách sử dụng:

import stringEnum from './stringEnum'; 
type Mode = "Silent" | "Normal" | "Deleted"; 
const Mode = stringEnum<Mode>(); 
0

Cách sạch nhất mà tôi tìm thấy cho đến nay là để tạo ra một bản đồ thứ:

let reverseMode = new Map<string, Mode>(); 
Object.keys(Mode).forEach((mode: Mode) => { 
    const modeValue: string = Mode[<any>mode]; 
    reverseMode.set(modeValue, mode); 
}); 

Vì vậy bạn có thể làm let mode: Mode = reverseMode.get('Silent');

Ưu điểm: không cần phải lặp lại các giá trị, cung cấp một cách để liệt kê enum, giữ TSLint hạnh phúc ...

Chỉnh sửa: Ban đầu tôi viết Mode[mode] nhưng sau đó TS có thể ném lỗi TS7015 trên dòng này, vì vậy tôi đã thêm diễn viên.

Các vấn đề liên quan