2012-10-06 25 views
17

tôi dường như không thể hiểu tại sao đoạn code sau đây không làm tăng lỗi:TypeScript: void return type được chuyển đổi thành bất kỳ loại nào?

var rg: {(): void;}[] = []; 
rg.push(function():string {return "";}) 

tôi nêu rõ rằng các loại nên là một mảng của các chức năng đó trở void, tuy nhiên tôi đẩy có một hàm trả về a string và trình biên dịch không phàn nàn. Nếu tôi thay đổi định nghĩa của rg thành

var rg: {():number;}[] = []; 

Trình biên dịch bắt đầu khiếu nại.

Đây có phải là lỗi hay không là cách kiểu trả lại void được cho là hoạt động (ví dụ: nếu có void được sử dụng, về cơ bản làm cho nó giống như kiểu trả về any)?

+0

Tôi đã [nộp một vấn đề] (http://typescript.codeplex.com/workitem/139). –

Trả lời

17

Đây là theo thiết kế (Tôi sẽ giải thích lý do tại sao thiết kế này nhanh chóng). Spec nói (trong phần 3.6.3, tóm tắt cho rõ ràng):

A type S is assignable to a type T, and T is assignable from S, if one of the following is true...

  • S and T are object types and, for each member M in T, one of the following is true:

    • M is a call, construct or index signature and S contains a call, construct or index signature N where

      • the result type of M is Void, or the result type of N is assignable to that of M.

Trong trường hợp này, chúng tôi đang thử nghiệm nếu () => string là chuyển nhượng để () => void. Vì vậy, string phải được gán cho void (không phải là) hoặc void phải là void (đúng).


Trong thực tế, các quy tắc ở đây là bạn được phép vứt bỏ giá trị trả về, đó là phù hợp với cách ví dụ C++ xử lý void ở độ phân giải mẫu.

function decrementWidgetHeight(w: Widget): number { 
    // ... returns the new height of the widget 
} 

function applyToManyWidgets(w: Widget[], change: (x: Widget) => void): void { 
    // for each widget in the array, apply 'change' to it 
} 

// Later... 
applyToManyWidgets(widgetsToShorten, decrementWidgetHeight); // Should be allowed? 

Khi chúng tôi hạn chế các loại change(widget) => void, chúng tôi đang làm cho nó để bạn có thể vượt qua decrementWidgetHeight như là đối số thứ hai mặc dù nó có một giá trị trả về, nhưng vẫn đảm bảo rằng khi chúng ta viết nội dung của applyToManyWidgets, chúng tôi không vô tình sử dụng giá trị trả lại là change ở bất kỳ đâu.

Lưu ý rằng void vẫn khác với any vì đây là thừa nhận:

function f() { } 
var x = f(); // Disallowed, f() is of type 'void' 
+0

+1 - bạn có thể kiểm tra điều này bằng cách sử dụng: 'var rg: {(): void;} [] = []; rg.push (function(): string {return "";}) var x = rg [0](); 'trong sân chơi TypeScript để xem hành vi hoạt động. Thay đổi 'void' thành' string' và nó sẽ cho phép sử dụng giá trị trả về. – Fenton

+0

Được rồi, nó có ý nghĩa, nhưng là một bộ đếm nhỏ trực quan, tức là cho phép thêm một hàm không phù hợp với loại, ngay cả khi nó bị vô hiệu trong định nghĩa. –

+1

Thông số này cũng cho biết "void chỉ liên quan đến các loại Undefined, Null và Any", vì vậy tôi không chắc thông số có nhất quán hay không. Chắc chắn là bất ngờ. – Roly

0

Trông giống như một lỗi. Bạn nên mở một số new work item cho sự cố

+0

[Đã làm điều đó] (https://typescript.codeplex.com/workitem/1734), nhưng đã đưa ra nhận xét ở trên, tôi đoán đây là dự định. Không tìm thấy generics sử dụng nhiều trong TS cho đến nay ... – Roly

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