これらのケースでは、TypeScriptをJavascriptにコンパイルするときに、効率が重視されます。つまり、必ずしも必要ではないコード(例えば、__extend
または__decorate
関数)は出力から除外されます。コンパイラに対するのは処理すべきものではありませんが、実行時の型のエラーは実際には実際の使用事例からも発生することがあります。
しかし、私はこのような実行時の型の不一致にエレガントなソリューションであることを起こる一つは活字体が提供すべて利点、残すための弱い理由であることを見つけるだろう:decoratorsを。特にreflect-metadataと組み合わせて使用する場合。
あなたはクラスのメソッドとしてm
を含めるとしたら、あなたは正しい型の値は、実行時に渡されていることを確認するためにmethod decoratorを使用することができます。
IMO
function TypeCheck(
target: any,
propertyKey: string,
propertyDescriptor: PropertyDescriptor
): any {
var originalMethod = target[propertyKey].bind(target);
var paramTypes = Reflect.getMetadata("design:paramtypes", target, propertyKey);
// Return a new property descriptor for the decorated method.
return {
value: function() {
// Check argument types.
for (var i = 0; i < arguments.length; i++) {
switch (paramTypes[i]) {
case String:
if (!(arguments[i] instanceof paramTypes[i]) && typeof arguments[i] !== "string") {
throw new TypeError(`Expected argument ${i} to be of type 'string'.`);
}
break;
case Number:
if (!(arguments[i] instanceof paramTypes[i]) && typeof arguments[i] !== "number") {
throw new TypeError(`Expected argument ${i} to be of type 'number'.`);
}
break;
case Boolean:
if (!(arguments[i] instanceof paramTypes[i]) && typeof arguments[i] !== "boolean") {
throw new TypeError(`Expected argument ${i} to be of type 'boolean'.`);
}
break;
default:
if (!(arguments[i] instanceof paramTypes[i])) {
throw new TypeError(`Expected argument ${i} to be of type '${paramTypes[i].prototype.toString.call(paramTypes[i]).toString()}'.`);
}
break;
}
}
// Call original method.
return originalMethod.apply(target, arguments);
}
};
}
class Foo {
@TypeCheck
public m(a: string) {
console.log(a + 12);
}
}
var foo = new Foo();
foo.m(13 as any); // Will throw TypeError.
これは、最も洗練されたソリューションを提供します。追加のワンタイムセットアップを追加する必要があります。はい、TypeCheck
デコレータは肥大化したように見えますが、ので、いくつかの種類がちょうど、追加チェックが必要です。
"some string" instanceof String; // false
...メタデータを反映させることで、プリミティブのタイプ情報としてラッパーオブジェクトも提供されます。
* "この問題のために私たちのプロジェクトのtypescriptをjsに置き換えてください。" *これはあなた次第です。この場合、* real *の問題は、作者が 'aが文字列である 'と書いたことです。これはコンパイラにあります(' aは文字列であると主張しています)'(http://www.typescriptlang.org/docs/handbook /jsx.html#the-as-operator)を参照してください。コンパイラにはない*文字列に*変換*する必要があります。 –
私は、** as **キーワードに関して最も大きな混乱があると思います。これは指定された型への**キャスト**ではありません。これは**型のアサーション**です。これを行うことで、コンパイラはaの型を文字列(実際の型に関係なく)とみなすべきです。 – toskv
ToskvとTJ Crowderは正確に正しいです。数値を文字列にキャストするには、.toString()またはJavaScriptのtype coersionを使用する必要があります。 'as'キーワードは、別の型への変数ではありません。 – Martin