TypeScript争论一个接口与通用类型T不兼容,尽管T扩展了该接口

时间:2019-03-14 01:52:16

标签: typescript generics

我遇到了一种特殊的行为。下面或后面的this typescript playground link

代码可以更好地解释
namespace Play {
    export interface BasicInterface {
        prop: any
    }

    export class Worker { 
        work(): BasicInterface {
            return { prop: "Hello" }
        }
    }

    export class Foo<T extends BasicInterface> {
        constructor(
            public worker: Worker,
            public workerCb: (workerResult: T) => any
        ) {}
        execute(): Promise<T> {
            return new Promise(res => {
                // Argument of type 'BasicInterface' is not assignable to parameter of type 'T'.
                res( this.workerCb(this.worker.work()) )
            }
        }    
    }
}
const foo = new Play.Foo<Play.BasicInterface>(new Play.Worker(), res => res)
foo.execute().then(res => console.log(res))

问题在第20行说

  

“ BasicInterface”类型的参数不能分配给“ T”类型的参数。

这很奇怪,因为T在Foo类声明中定义为T extends BasicInterface,所以它应该与BasicInterface完全兼容。

因此,问题是:为什么这样以及如何解决?

UPDATE 我现在更加困惑,因为使用this似乎可以使用TS,这是相同的(-ish?),或者我看不出它有什么不同...

namespace Play {
    export interface BasicInterface {
        prop: any
    }
    export class Implmentor implements BasicInterface {
        prop = "Hello"
    }
    export class Foo<T extends BasicInterface> {
        constructor(thingy: T) { }
    }
}

new Play.Foo(new Play.Implmentor())
new Play.Foo({prop: "Yay!"})

1 个答案:

答案 0 :(得分:2)

这是正确的错误。

您的班级合同表明此代码是合法的:

numpy.correlate(x,y)

但是您的实现无法产生任意的var http = require('http'); var url = require('url'); http.createServer(onRequest).listen(3000); function onRequest(client_req, client_res) { var queryData = url.parse(client_req.url, true).query; var urlInfo = url.parse(queryData.url, true) var options = { hostname: urlInfo.hostname, path: urlInfo.path, method: client_req.method, headers: client_req.headers }; var proxy = http.request(options, function (res) { client_res.writeHead(res.statusCode, res.headers) res.pipe(client_res, { end: true }); }); client_req.pipe(proxy, { end: true }); } ,而只会产生interface BetterInterface extends Play.BasicInterface { thing: string; } const foo = new Play.Foo<BetterInterface>(new Play.Worker(), res => res) // Throws an exception because 'thing' is undefined foo.execute().then(res => console.log(res.thing.toUpperCase))

另请参阅Why can't I return a generic 'T' to satisfy a Partial<T>?