0

Is there a way to use the conditional type NonNullable<T>, inside the declaration block of T, getting the same result as de function bellow. Or a simpler way to get the same result?


function logObj<
  T extends string | boolean | string | object | ((...args: any) => any)
>(obj: T) {
  console.log(obj);
}

logObj({});
logObj("");
logObj({ foo: "foo" });
//logObj(null); // proper compilation error
//logObj(undefined); // proper compilation error

I have tried the approach bellow, but it is does not compile.


namespace CompilationError {
  //                        Compilation Error: Type parameter 'T' has a circular constraint.
  //                        ↓
  function logObj<T extends NonNullable<T>>(obj: T) {
    console.log(obj);
  }

  logObj({});
  logObj("");
  logObj({ foo: "foo" });
  //logObj(null); // proper compilation error
  //logObj(undefined); // proper compilation error
}

The solutions bellow works, but I would like to use the type constraint right after the Type Parameter declaration.


namespace NonNullableInsideArgumentType {
  function logObj<T>(obj: NonNullable<T>) {
    console.log(obj);
  }
  logObj({});
  logObj("");
  logObj({ foo: "foo" });
  //logObj(null); // proper compilation error
  //logObj(undefined); // proper compilation error
}


namespace NonNullableUsingUnionTypes {
  function logObj<T extends NonNullable<string | boolean | string | object | ((...args: any) => any)>>(obj: T) {
    console.log(obj);
  }

  logObj({});
  logObj("");
  logObj({ foo: "foo" });
  //logObj(null); // proper compilation error
  //logObj(undefined); // proper compilation error
}

Cássio
  • 149
  • 2
  • 10
  • 1
    No, you can't do this directly. What is wrong with `(x: NonNullable): void`? You *can* write `(x: T): void` but that's worse, isn't it? – jcalz Feb 25 '20 at 02:19
  • Thanks, nothing works perfectly, but I would like to know if there is a simpler way to do this. I had scenario where the function has two arguments, in that case seemed more appropriate to move the generic constraint to the Type parameter definition, in order to reuse de constraint, but if it is not possible that's fine. – Cássio Feb 25 '20 at 02:31

0 Answers0