typescripttype-inferenceconditional-typesgeneric-type-parameters

How to make return type depend on parameter type


i have a method like this public myMethod(param: MyClass | null): MyClass | null i want to somehow communicate, that the output is null only if the parameter is null. so if you pass in an instance of MyClass it will not return null.

what has been tried:

public myMethod<T extends MyClass | null>(param: T): T extends null ? null : MyClass {
  if (param === null) {
    return null;
  }

  return new MyClass(param.cnt + 1); // just an example, generally the constructor param is some value derived from the param
}

but that doesn't work - complains that "MyClass isn't assignable to T extendss null ? null : MyClass"


Solution

  • This is a common use case for function overloads. It works by providing a number of separate signatures in addition to the implementation signature.

    class Test {
        public myMethod(param: null): null;
        public myMethod(param: MyClass): MyClass;
        public myMethod(param: MyClass | null): MyClass | null {
          if (param === null) {
            return null;
          }
    
          return new MyClass(); // just an example, generally the constructor param is some value derived from the param
        }
    }
    

    The first two signatures are the overload signatures, they will be used to check argument types and determine the return type where you call the method. The last one is the implementation signature, it has to be compatible with the overload signatures and the function implementation but can't be called directly.