Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript generics "extends" constraint: Is there a nullable constraint?

It looks like the following doesn't compile:

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

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

This yields TS2322: Type 'INullableServiceBase' cannot be assigned to type 'T'. Type 'undefined' cannot be assigned to type 'T'.

How can I define a generic constraint to allow nullable types?

like image 502
AxD Avatar asked Nov 24 '25 19:11

AxD


1 Answers

The problem is that the caller is the one deciding T. If this._service is defined to be IServiceBase | null you have two problems.

  1. T might be IServiceBase so assigning IServiceBase | null is not type safe since this._service might be null
  2. T might be a type derived from IServiceBase, (ie IExtendedServiceBase). So this._service will not satisfy that T in any way.

These reasons are enough to make the compiler reject this. You could force things with a type assertion (this._service as T), or you might consider not making this generic at all, since the caller is not really in control of T:

function GetService(): INullableServiceBase
{
  return this._service;
}

Or making the containing class generic on the service type:

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

But without more context it is difficult to say what will work best.

like image 169
Titian Cernicova-Dragomir Avatar answered Nov 26 '25 12:11

Titian Cernicova-Dragomir



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!