23

次のコードでエラーが発生しない理由を理解できないようです。

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

型は戻り値を返す関数の配列である必要があることを明確に述べてvoidいますが、を返す関数をそこにプッシュしてもstring、コンパイラーは文句を言いません。の定義をに変更したrg場合

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

コンパイラは文句を言い始めます。

これはバグですか、それともvoid returnタイプがどのように機能するのでしょうか(つまりvoid、使用された場合は何でも起こり、基本的にreturnタイプと同じになりanyます)?

4

1 に答える 1

29

これは仕様によるものです (これが優れた設計である理由については後ほど説明します)。仕様には次のように記載されています(セクション3.6.3では、明確にするために要約されています):

次のいずれかが真の場合、型 S は型 T に代入可能であり、T は S から代入可能です...

  • S と T はオブジェクト型であり、T の各メンバー M について、次のいずれかが true になります。

    • M は呼び出し、構成、またはインデックス シグネチャであり、S には呼び出し、構成、またはインデックス シグネチャ N が含まれます。

      • M の結果の型が Void であるか、N の結果の型が M の結果の型に代入可能です。

この場合、() => stringが に割り当て可能かどうかをテストしています() => void。したがって、割り当て可能でなければならない (string割り当てられvoidない) か、割り当て可能でなければならない (割り当てられる) 必要voidがありvoidます。


事実上、ここでの規則は、戻り値を破棄することが許可されているということですvoid。これは、たとえば C++がテンプレート解決で処理する方法と一致しています。

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?

の型を に制約するchangeと、戻り値があっても 2 番目の引数として(widget) => void渡すことができるようになりますが、 の本体を記述するときに誤って を使用しないようにします。どこでも戻り値。decrementWidgetHeightapplyToManyWidgetschange

これは許可されていないため、とvoidはまだ異なることに注意してください。any

function f() { }
var x = f(); // Disallowed, f() is of type 'void'
于 2012-10-06T21:06:26.243 に答える