TypeScript泛型“extends”约束:是否有可空约束?

3

看起来以下内容无法编译:

interface IServiceBase {};
type INullableServiceBase = IServiceBase | undefined;

public GetService<T extends INullableServiceBase>(): T
{
  return this._service;
}

这将产生 TS2322 错误: 类型 'INullableServiceBase' 不能赋值给类型 'T'。类型 'undefined' 不能赋值给类型 'T'。

我该如何定义一种泛型约束以允许可空类型?

1个回答

1
问题在于调用者决定了T。如果this._service被定义为IServiceBase | null,那么你会遇到两个问题:
  1. T可能是IServiceBase,因此分配IServiceBase | null不是类型安全的,因为this._service可能为null。
  2. T可能是从IServiceBase派生出来的类型(即IExtendedServiceBase)。所以this._service将无法满足T
这些原因足以使编译器拒绝此操作。您可以使用类型断言(this._service as T)强制进行操作,或者考虑根本不使其成为通用型,因为调用者并不能真正控制T
function GetService(): INullableServiceBase
{
  return this._service;
}

或者将包含类泛型化为服务类型:

class ServiceFactory<T extends INullableServiceBase> {
    constructor(private _service: T) { }
    public GetService(): T {
        return this._service;
    }
}

但是,如果没有更多的上下文,很难说什么才是最好的。


实际上,我一直在使用你的第一个建议。但是我想切换到通用方法。然而,由于GetService()函数只是我的控制器类的一个小部分,我不想将其类型添加到类的定义中。非常感谢你指出这些问题! - AxD

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接