Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Typescript generics: types 'T' and 'number' have no overlap error

Consider this example:

function foo<T>(t: T): boolean {
  return t === 1;
}

I get This condition will always return 'false' since the types 'T' and 'number' have no overlap..

The error goes away if I change it to:

function foo<T extends any>(t: T): boolean {
  return t === 1;
}

I thought T could be any by default, so why did I need extends any? Without extends any, what type does TS expect T to be?

Edit, actual function:

function cleanObj<T>(
  obj: ObjectOf<T>,
): ObjectOf<T> {
  const newObj = {};
  for (const k of Object.keys(obj)) {
    if (obj[k] !== null && typeof obj[k] !== 'undefined' && obj[k] !== false) {
      newObj[k] = obj[k];
    }
  }

  return newObj;
}
like image 496
Leo Jiang Avatar asked Sep 08 '20 06:09

Leo Jiang


2 Answers

The triple equals operator === returns true if both operands are of the same type and contain the same value. Compared to that "1" == 1 would return true.

Since you use === you also compare the type, which is number for the right hand operant 1. However, your T can not just be a number, that is why the compiler gives you this notification.

Possible solutions:

  • remove the generics if not really necessary
  • use == instead of ===
  • (possible further approaches depending on your actual code)
like image 52
MoxxiManagarm Avatar answered Nov 20 '22 07:11

MoxxiManagarm


Partially taken from https://github.com/microsoft/TypeScript/issues/17445 :

Consider your original function:

function compare<T>(obj: T): boolean {
  return obj === 1;
}

if it would be allowed to compare anything to T we could also write:

function compare<T>(obj: T): boolean {
  return obj === 'some-string-thats-definitely-not-obj';
}

If you use that function inside of some if, you could potentially create unreachable code that won't throw an error.

This is why typescript requires you to explicitely tell it that T can be any, which is obviously unsafe for the above reason.

like image 42
Mike S. Avatar answered Nov 20 '22 07:11

Mike S.