2016-05-03 20 views
8

Tôi muốn MyInterface.dic trở nên giống như một cuốn từ điển name: value, tôi định nghĩa nó như sau:nguyên cảo: Index chữ ký là mất tích trong loại

interface MyInterface { 
    dic: { [name: string]: number } 
} 

Bây giờ tôi tạo ra một chức năng mà đợi cho loại của tôi:

function foo(a: MyInterface) { 
    ... 
} 

Và đầu vào:

let o = { 
    dic: { 
     'a': 3, 
     'b': 5 
    } 
} 

tôi đang mong đợi foo(o) là đúng, nhưng trình biên dịch đang giảm:

foo(o) // Typescript error: Index signature is missing in type { 'a': number, 'b': number } 

Tôi biết có một đúc càng tốt: let o: MyInterface = { ... } mà làm các trick nhưng câu hỏi là, tại sao nguyên cảo không nhận ra loại của tôi?


thêm: hoạt động tốt nếu o được khai báo inline:

foo({ 
    dic: { 
    'a': 3, 
    'b': 5 
    } 
}) 

Trả lời

9

Vấn đề là khi loại được suy ra, sau đó loại o là:

{ dic: { a: number, b: number } } 

Đó không phải là giống như { dic: { [name: string]: number } }. Nghiêm túc, với chữ ký đầu bạn không được phép làm điều gì đó như o.dic['x'] = 1. Với chữ ký thứ hai bạn đang có.

Chúng là các loại tương đương trong thời gian chạy (thực sự, chúng là giá trị giống nhau), nhưng phần lớn an toàn của TypeScript xuất phát từ thực tế là chúng không giống nhau và chỉ cho phép bạn xử lý một đối tượng làm từ điển nếu nó biết nó được dự định rõ ràng là một đối tượng. Đây là những gì khiến bạn vô tình đọc và viết các thuộc tính hoàn toàn không tồn tại trên các đối tượng.

Giải pháp là đảm bảo TypeScript biết rằng nó được dùng làm từ điển. Điều đó có nghĩa:

  • Rõ ràng cung cấp một loại ở đâu đó mà nói với nó đó là một từ điển:

    let o: MyInterface

  • Khẳng định đó là một inline từ điển:

    let o = { dic: <{ [name: string]: number }> { 'a': 1, 'b': 2 } }

  • Đảm bảo đó là kiểu ban đầu mà TypeScript cung cấp cho bạn:

    foo({ dic: { 'a': 1, 'b': 2 } })

Nếu có một trường hợp nguyên cảo nghĩ đó là một đối tượng bình thường chỉ với hai thuộc tính, và sau đó bạn cố gắng sử dụng nó sau này như một cuốn từ điển, nó sẽ được hạnh phúc.

+0

> Với chữ ký thứ hai của bạn. Trên thực tế, donot của IDE của tôi cho phép tôi thực hiện 'o.dic.x' – Manu

+1

Bắt tốt, xin lỗi, đó nên là cú pháp chỉ mục ('o.dic ['x'] = 1'). Đã cập nhật ví dụ. –

+2

Cập nhật! Giờ đây, TypeScript 2 sẽ tự động thực hiện chuyển đổi này cho bạn, nếu nó hợp lệ: https://github.com/Microsoft/TypeScript/wiki/What%27s-new-in-TypeScript#implicit-index-signatures –

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