【问题标题】:Type 'T' is not assignable to type 'T'类型“T”不能分配给类型“T”
【发布时间】:2016-07-31 17:40:18
【问题描述】:

我是一位经验丰富的 javascript 开发人员,最近学习了 C# 作为我的第一个静态类型语言。我的下一个项目是使用打字稿,所以我一直在复习。

这是我的代码:

interface IMonad<T> {
    get(): T;
    set<T>(fn: (value: T) => T): IMonad<T>;
}

class LazyMonad<T> implements IMonad<T>
{
    private value: T;
    private binds;

    constructor(value: T)
    {
        this.value = value;
        this.binds = [];
    }

    get(): T
    {
        return this.binds
            .reduce(function (v: T, fn): T {
                return (v === null) ? null : v + fn(v);
            }, this.value);
    }

    set<T>(fn: (value: T) => T): LazyMonad<T>
    {
        this.binds.push(fn);
        return this;
    }
}

编辑:我也有这个实现IMonad&lt;T&gt;的类

class IdentityMonad<T> implements IMonad<T>
{
    private value: T;

    constructor(value: T)
    {
        this.value = value;
    }

    get(): T
    {
        return this.value;
    }

    set<T>(fn: (value: T) => T): IdentityMonad<T>
    {
        return new IdentityMonad<T>(fn(this.value));
    }
}

这是我从tsc 得到的错误:

src/lazy_monad.ts(25,10):错误 TS2322:类型“this”不可分配 输入“LazyMonad”。类型“LazyMonad”不可分配给 输入“LazyMonad”。 类型“T”不能分配给类型“T”。

我的实现在这里可能是错误的,但我相信这在 C# 中可以工作。建议?

【问题讨论】:

  • 您的意思是让set&lt;T&gt; 通用吗?我认为您可能希望它使用类中的T 而不是方法中的T 来获取/设置

标签: typescript


【解决方案1】:

我相信你可能想让set 使用类中的T 而不是它有自己的通用约束。删除它将修复您的错误。

从那里您可能要考虑使用多态 this:

interface IMonad<T> {
    get(): T;
    set(fn: (value: T) => T): this; // use this as the return type
}

class LazyMonad<T> implements IMonad<T>
{
    private value: T;
    private binds: ((value: T) => T)[]; // you might want to add this type here too

    constructor(value: T)
    {
        this.value = value;
        this.binds = [];
    }

    get()
    {
        return this.binds
            .reduce(function (v: T, fn): T {
                return (v === null) ? null : v + fn(v);
            }, this.value);
    }

    set(fn: (value: T) => T)
    {
        this.binds.push(fn);
        return this;
    }
}

// lazyMonad would be typed as LazyMonad<number> here
var lazyMonad = new LazyMonad(5).set((val) => val);

这也适用于IdentityMonad

有关其工作原理的更多详细信息,请参阅“this-typing”部分here

【讨论】:

  • 我有另一个类 IdentityMonad 实现了 IMonad 但 set() 每次调用时都会返回一个新的 IdentityMonad 。这是否违反了我目前拥有的界面的合同?我还在学习打字范式。
  • @Kylee 我刚刚意识到set&lt;T&gt; 是通用的。
  • 从集合中移除通用约束是有效的,这说明为什么它不起作用。谢谢!
猜你喜欢
  • 2019-03-04
  • 2020-08-19
  • 2016-09-20
  • 2017-12-29
  • 2019-01-31
  • 2019-11-17
  • 2022-11-11
  • 2022-11-11
  • 2022-08-08
相关资源
最近更新 更多