【问题标题】:I get a type '{}' where I should be getting a type number (TypeScript)我得到一个类型“{}”,我应该得到一个类型号(TypeScript)
【发布时间】:2014-12-09 09:07:34
【问题描述】:

在下面的 TypeScript 代码中,它是一个更完整的类的子集,我有一些函数,例如 map 和 foldr。当我运行以下代码时:

var s = new ArrayList<number>();
s.append(5, 6, 7, 8);

var i : number = s.foldr(max, 0);

我最终得到一个错误,例如“Type '{}” is notassignable to type 'number'。”我想,类型应该是一个数字。我会这样证明:

foldr 的类型签名为: foldr(f : (x : T, y : B) => B, init : B) : B。因为 T 来自 ArrayList,所以它是一个数字。该函数作为 0 传递给 init,这是一个数字,max 是 max(x : T, y : T) : T 设置 B = T 因为 x 是 T(即使它们可能是不同的 T,但它们不在本例)。

但无论如何,我仍然收到此错误。我犯了一个根本性的错误吗?

代码示例如下,也可在gistsplayground 上找到。

class ArrayList<T> {
    private _data : Array<T>;

    public constructor() {
        this._data = new Array<T>();
    }

    public get length():number { return  this._data.length; }

    public append(...items : T[]) : void {
        this._data = this._data.concat(items);
    }

    public get(n : number) : T {
        return this._data[n];
    }

    public foldr<B>(f : (x : T, y : B) => B, init : B) : B {
        if (this.length == 0) return init;

        var result = init;

        for (var i = this._data.length - 1; i >= 0; --i) {
            result = f(this._data[i], result);
        }

        return result;
    }

}

function max<T>(x : T, y : T) : T {
    return x > y ? x : y;
}

var s = new ArrayList<number>();
s.append(5, 6, 7, 8);

//  Type '{}" is not assignable to type 'number'.
var i : number = s.foldr(max, 0); 

【问题讨论】:

    标签: typescript


    【解决方案1】:

    示例代码中的foldr 方法采用类型参数&lt;B&gt;

    var i : number = s.foldr<number>(max, 0); 
    

    虽然,也许你不打算这样做。这个版本重新使用了T 类型参数,这意味着一切正常(尽管您必须确保这是您想要的)。

    public foldr(f : (x : T, y : T) => T, init : T) : T {
        if (this.length == 0) return init;
    
        var result = init;
    
        for (var i = this._data.length - 1; i >= 0; --i) {
            result = f(this._data[i], result);
        }
    
        return result;
    }
    

    【讨论】:

    • 我不是故意的,因为它应该能够更通用。之所以这样,主要是因为 Haskell source for foldr,类型为 (a -> b -> b) -> b -> [a] -> b。我相信原因是您可能希望将列表的类型转换为其他类型,例如转换为字符串。
    • 如果您希望它更通用,请使用第一个代码块(即提供类型参数)。如果您希望它是 number,因为 ArrayList 具有数字类型参数,请使用第二个。
    • 所以本质上必须提供类型参数,而不是从参数推断?
    • 阅读规范的第 1.9 节,它确实表明它可以推断参数 - 但它总是在示例中使用 lambdas。所以也许我真正想弄清楚的是这个推断的局限性。
    • 不排除未来会有更好的推理——但这是目前的位置。
    猜你喜欢
    • 2017-11-19
    • 1970-01-01
    • 2023-04-07
    • 2021-05-02
    • 2022-11-30
    • 2021-12-04
    • 2021-09-18
    • 2021-06-06
    相关资源
    最近更新 更多