8

タイプの要素を配列に追加anyし、後でこの配列から数値である要素を取得したい:

function OfType<T, U>(list: T[]) : U[]
{
    var result: U[] = [];

    list.forEach(e => {
        // I want to check if e is of type U
        //if (typeof(e) === typeof(U)) // ERROR: doesn't work
            result.push(<U><any>e);
    });

    return <any[]>result;
}


var list: any[] = [];
list.push("A");
list.push(2);

var result = OfType<any, number>(list);

alert(result.toString());

しかし、ジェネリック型に対して要素の型をチェックすることはできません。

これを達成する方法はありますか?

4

3 に答える 3

1

Javascript typeof は、型自体ではなく、オブジェクトのインスタンスに対して機能します。(結局のところ、コンパイルされた JavaScript では TypeScript ジェネリックが消えます。)

U のインスタンスを取得し、それに対して typeof を呼び出し、それを typeof(e) と比較する必要があります。

JavaScript の型情報は、.NET フレームワークのように豊富ではないことに注意してください。オブジェクトがクラス Foo のインスタンスであっても、typeof(myCustomObject) は「オブジェクト」を返します。

あなたの場合、配列を数値のみにフィルタリングする .OfType メソッドを構築しようとしています。次のように記述できます。

var list: any[] = [];
list.push("A");
list.push(2);
var numbers = list.filter(e => typeof(e) === "number");
于 2013-06-30T19:20:38.447 に答える
1

Judahが指摘したように、ジェネリック型だけを使用することはほとんど不可能です。タイプでもう1つのパラメーターを送信する回避策を見つけました...

function OfType<T, U>(list: T[], arg: Function) : U[]
{
    var result: U[] = [];

    list.forEach(e => {
        // extract the name of the class
        // used to match primitive types
        var typeName = /function\s*([^(]*)/i.exec(arg+"")[1].toLocaleLowerCase();

        var isOfType = typeof(e) === typeName;

        // if it is not primitive or didn't match the type
        // try to check if it is an instanceof
        if (!isOfType)
        {
            try {
                isOfType = (e instanceof arg)
            }
            catch (ex) { }
        }

        if (isOfType)
            result.push(<U><any>e);
    });

    return <any[]>result;
}

使用法:

var numbers = OfType<any, number>(list, Number);
var foos = OfType<any, Foo>(list, Foo);

alert("Numbers: " + numbers);
alert("Foos: " + foos);

冗長性はほとんどありません。誰かがこの冗長性を取り除く方法を知っている場合は、コメントを残すか、このコードを編集してください。

filterまたは、ユダが述べたように、プリミティブ型のみを使用できました。

于 2013-06-30T20:00:34.433 に答える