【问题标题】:Typescript : generic not inferred打字稿:通用未推断
【发布时间】:2022-01-25 14:45:45
【问题描述】:

我是 Typescript 的新手,来自 Java/Kotlin。我有这个脚本:

class RequestMessage<ResponseType> {}
class NewOrderRequestMessage extends RequestMessage<OrderFilled | OrderCancelled> {}

async function sendMessage<T>(requestMessage:RequestMessage<T>): Promise<T> {
    return new Promise<T>((resolve, reject) => {
        // ...
    })
}

(async () => {
    let requestMessage = new NewOrderRequestMessage()
    let result = await sendMessage(requestMessage)
})()

我的问题是结果类型被推断为“未知”,而我希望它被推断为OrderFilled | OrderCancelled,因为 sendMessage 的参数是RequestMessage&lt;OrderFilled | OrderCancelled&gt;

通常,在 Java/Kotlin 中,相同的逻辑可以正确推断出 result

class Promise<T>()

open class RequestMessage<T> {}
class NewOrderRequestMessage : RequestMessage<Int>() {}

fun <T> sendMessage(requestMessage: RequestMessage<T>): Promise<T> {
    return Promise()
}

val requestMessage = NewOrderRequestMessage()
val result = sendMessage(requestMessage)

在这个等效的 Kotlin 脚本中,结果被推断为 Promise&lt;Int&gt;

为什么不能在 Typescript 中?由于这种未知类型,当 sendMessage 返回另一种类型的 Promise 时,Typescript 不会在编译时给我错误,给我带来奇怪的情况。我希望响应类型是 OrderFilled 或 OrderCancelled,但 sendMessage 实际上可以解析为一个承诺完全不相关的类型,没有任何编译错误,在运行时会产生意外和未处理的异常。

【问题讨论】:

    标签: typescript kotlin generics


    【解决方案1】:

    TS 不是强类型语言,它的类型系统仅与形状有关。 那就是说NewOrderRequestMessage 不再是通用的。
    如果您将其转换为RequestMessage&lt;OrderFilled | OrderCancelled&gt;,那么推断将正常工作:

    interface OrderFilled {
    
    }
    
    interface OrderCancelled {
    
    }
    
    class RequestMessage<ResponseType> {}
    class NewOrderRequestMessage extends RequestMessage<OrderFilled | OrderCancelled> {}
    type RequestMessageWithOrder  = RequestMessage<OrderFilled | OrderCancelled>
    
    async function sendMessage<T>(requestMessage:RequestMessage<T>): Promise<T> {
        return new Promise<T>((resolve, reject) => {
            // ...
        })
    }
    
    (async () => {
        let requestMessage: RequestMessageWithOrder = new NewOrderRequestMessage()
        let result = await sendMessage(requestMessage)
    })()
    

    使用代码here

    【讨论】:

    • 太棒了!有道理,谢谢你的反应:)
    猜你喜欢
    • 1970-01-01
    • 2021-08-31
    • 2020-08-27
    • 2020-08-06
    • 2019-07-30
    • 2020-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多