TypeScript泛型“扩展”约束:是否存在可为空的约束?

时间:2019-03-18 13:02:51

标签: typescript typescript-generics

似乎无法编译以下内容:

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

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

这将产生TS2322:类型“ INullableServiceBase”不能分配为类型“ T”。无法将“未定义”类型分配给“ T”类型。

如何定义通用约束以允许可空类型?

1 个答案:

答案 0 :(得分:1)

问题在于,呼叫者是决定T的那个。如果将this._service定义为IServiceBase | null,则有两个问题。

  1. T可能是IServiceBase,所以分配IServiceBase | null的类型不安全,因为this._service可能为空
  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;
    }
}

但是如果没有更多的背景信息,很难说出哪种方法最有效。