2015-06-11 28 views
9

Không thể đặt kiểu tham số thành Enum? Như thế này:Giả sử tham số trong kiểu số

private getRandomElementOfEnum(e : enum):string{ 
    var length:number = Object.keys(e).length; 
    return e[Math.floor((Math.random() * length)+1)]; 
} 

Nếu tôi làm như vậy, Intellij đánh dấu mã này là không xác định. Và đề xuất đổi tên biến, điều đó có hợp lý không?

private getRandomElementOfEnum(e : any):string{ 
    var length:number = Object.keys(e).length; 
    return e[Math.floor((Math.random() * length)+1)]; 
} 

Mã này hoạt động tốt. nhưng không phải là thanh lịch và quy ước.

Có khả năng hoặc một giải pháp nhỏ để xác định enum là tham số không?

EDIT:

Sau khi nghiên cứu những câu trả lời, tôi có thể làm được điều này cũng với ah bộ enum định nghĩa, sth tương tự như enum1 | enum2 | enum3?

+2

Không nên là 'e: MyEnumType'? Hay bạn muốn chấp nhận bất kỳ loại enum nào. Làm thế thì được ích gì? Bạn cũng có thể làm 'e: MyEnum | MyOtherEnum | MyThirdEnum'. – Thilo

+0

Có liên quan (nhưng có thể lỗi thời): http: // stackoverflow.com/questions/21293063/how-to-programmatically-enumerate-an-enum-type-in-typescript-0-9-5? rq = 1 – Thilo

+0

mọi enum nên có thể, vì vậy tôi có thể nhận được phần tử ngẫu nhiên ah của mỗi enum bằng cách gọi hàm này. – Synoon

Trả lời

8

Không thể đảm bảo tham số là một enum, bởi vì liệt kê trong TS không kế thừa từ một tổ tiên chung hoặc giao diện.

TypeScript mang đến phân tích tĩnh. Mã của bạn sử dụng lập trình động với Object.keyse[dynamicKey]. Đối với các mã động, loại any thuận tiện.

Mã của bạn là buggy: length() không tồn tại, e[Math.floor((Math.random() * length)+1)] trả về một chuỗi hoặc một số nguyên, và the enumeration values can be manually set ...

Dưới đây là một gợi ý:

function getRandomElementOfEnum<E>(e: any): E { 
    var keys = Object.keys(e), 
     index = Math.floor(Math.random() * keys.length), 
     k = keys[index]; 
    if (typeof e[k] === 'number') 
     return <any>e[k]; 
    return <any>parseInt(k, 10); 
} 

function display(a: Color) { 
    console.log(a); 
} 

enum Color { Blue, Green }; 
display(getRandomElementOfEnum<Color>(Color)); 

Lý tưởng nhất, các tham số kiểu any nên thay thế bởi typeof E nhưng trình biên dịch (TS 1.5) không thể hiểu cú pháp này.

+0

hehe, mã của tôi đã thực sự lỗi, tôi nhận ra nó khoảng 10 phút sau, quên thay đổi mã ở đây .. – Synoon

10

Bạn có thể làm tốt hơn so với any:

enum E1 { 
    A, B, C 
} 
enum E2 { 
    X, Y, Z 
} 

function getRandomElementOfEnum(e: { [s: number]: string }): number { 
    /* insert working implementation here */ 
    return undefined; 
} 

// OK 
var x: E1 = getRandomElementOfEnum(E1); 
// Error 
var y: E2 = getRandomElementOfEnum(window); 
// Error 
var z: string = getRandomElementOfEnum(E2); 
+0

Trình biên dịch giả định rằng 'E1' khớp với loại' {[s: number]: string} ', nhưng là nó lâu năm? Đối tượng 'E1' chứa các chuỗi ký tự. – Paleo

+3

Số chỉ mục không hạn chế các loại khóa không phải số –

3

Tôi đồng ý với @Tarh. Enums trong TypeScript chỉ là các đối tượng Javascript mà không có một giao diện chung hoặc nguyên mẫu (và nếu chúng là const enum, thì chúng không phải là đối tượng), vì vậy bạn không thể hạn chế các loại thành "bất kỳ enum" nào.

Gần nhất tôi có thể nhận được là một cái gì đó như sau:

enum E1 { 
    A, B, C 
} 
enum E2 { 
    X, Y, Z 
} 

// make up your own interface to match TypeScript enums 
// as closely as possible (not perfect, though) 
interface Enum { 
    [id: number]: string 
} 

function getRandomElementOfEnum(e: Enum): string { 
    let length = Object.keys(e).length/2; 
    return e[Math.floor((Math.random() * length))]; 
} 

này làm việc cho tất cả các sự đếm, nhưng nó cũng sẽ chấp nhận các mảng khác như là đầu vào (và sau đó thất bại vì cơ thể phương pháp dựa trên rất cụ thể cấu trúc khóa mà các EnScript TypeScript có). Vì vậy, trừ khi bạn có nhu cầu thực sự về chức năng "chung" như vậy, hãy thực hiện các chức năng an toàn cho các loại enum riêng lẻ (hoặc loại công đoàn như E1|E2|E3) mà bạn thực sự cần.

Và nếu bạn có nhu cầu này (và điều này rất có thể là một vấn đề X-Y có thể được giải quyết theo cách hoàn toàn khác, tốt hơn), hãy sử dụng any, vì bạn vẫn để lại lãnh thổ an toàn.

+0

Tôi chưa thử nghiệm lý thuyết này nhưng tôi khá chắc chắn việc triển khai của bạn không hỗ trợ 'enum E3 {X = 4, Y, Z}' –

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