【问题标题】:Argument not assignable to parameter of type T参数不可分配给类型 T 的参数
【发布时间】:2017-06-23 08:57:07
【问题描述】:

我已经定义了接口IDictionary如下:

interface IDictionary<T = any> {
  [key: string]: T;
}

然后我将这个类型 T 传递给 db.update() 函数,该函数定义为:

public update<T = IDictionary>(path: string, value: T) {
  return this.ref(path).update(value);
}

当我尝试编译此文件时,我收到以下错误:

src/shared/Model.ts (64,7): 类型参数 '{ lastUpdated: string; }' 不可分配给“T”类型的参数。 (2345)

考虑到IDictionary&lt;any&gt; 类型是默认的“T”,我不明白为什么这不会被认为是有效的。是不是我做错了什么?

演示错误的完整示例:

interface IDictionary<T = any> {
  [key: string]: T;
}

function dbupdate<T = IDictionary>(path: string, value: T) {
  return this.ref(path).update(value);
}

abstract class Model<T = IDictionary> {

    public update(updateWith: IDictionary) {

        const reference = 'bar';
        return dbupdate<T>(
            reference,
            {
                ...updateWith,
                ...{ lastUpdated: 'baz' }
            }
        );
    }
}

【问题讨论】:

  • 问题不在于您发布的代码,而在于您如何使用它。所附图像未显示所有相关代码,仅显示其结尾。这是什么T
  • 在上图中,您可以在悬停对话框中看到类型分辨率...默认为IDictionary&lt;any&gt;
  • 请使用其余相关代码更新您的问题。如果有一些其他人可以用来重现您的问题,那就太好了。
  • 好的,不确定要包含哪些内容,所以我将整个文件添加到 gist 此处:gist.github.com/ksnyde/806b2e3439157d55bd0cf70c8ec5aa88

标签: typescript typescript2.0


【解决方案1】:

在您的 Model 类声明中

abstract class Model<T = IDictionary> { 

T 是泛型类型参数,可以是任何东西。 IDictionary 是默认值,并不意味着T 将始终与IDictionary 兼容。没有什么可以阻止某人像这样使用您的Model

let myModel: Model<string> = ...

Typescript 告诉您,在一般情况下,您为 db.update 的第二个参数构造的值与 T 不兼容。

使其编译的最简单方法是像这样更改 db.update 调用

    return dbupdate<IDictionary>(
        reference,
        {
            ...updateWith,
            ...{ lastUpdated: 'baz' }
        }
    );

但是我不知道您通过使用通用参数T 来实现什么,所以这可能不是正确的解决方案。

【讨论】:

  • Model 是其他模型继承自的基类,因此 将指示给定具体子类的接口定义。我认为有一种方法可以在更新期间关闭类型特异性,并在其他地方进行类型转换。所以在某种程度上我已经在其他地方解决了我的问题,但对于这个问题的意图,我觉得你已经很好地解决了这个问题。
猜你喜欢
  • 2020-08-19
  • 2018-05-08
  • 2019-07-27
  • 2019-06-24
  • 2021-06-14
  • 2017-07-14
  • 2019-01-08
  • 2018-08-10
相关资源
最近更新 更多