question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Types `number` and explicitly constrained `T extends unknown` shouldn't be comparable

See original GitHub issue
const num = 1;
function check<T extends unknown>(x: T) {
  return x === num;
}
check(num);

Expected: Error: This condition will always return ‘false’ since the types ‘T’ and ‘1’ have no overlap. Actual: No error.

Contrast this with the following example from #32768.

const num = 1;
function check<T>(x: T) {
  return x === num;
}
check(num);

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:1
  • Comments:24 (10 by maintainers)

github_iconTop GitHub Comments

5reactions
davidje13commented, Aug 13, 2019

I think this will be my last comment on this issue, because it doesn’t affect me too strongly (I can always use as any to get around any errors introduced), but to give a more concrete (but still contrived) example, since I think a lot of people are getting hung-up on the simplicity of isSame:

function mapReversed<T, U>(source: T[], target: U[], map: (t: T) => U): void {
  const count = source.length;
  if (target.length !== count) {
    throw new Error('target length mismatch');
  }
  if (source === target) {
    // cannot reverse in-place, so perform extra steps
    // (uses more memory, builds up garbage for the gc to handle, and is slower, but guarantees correctness)
    const mapped = source.map(map);
    for (let i = 0; i < count; i++) {
      target[count - i - 1] = mapped[i];
    }
  } else {
    // reversing in-place is fine; use optimised code (no garbage generated for gc)
    for (let i = 0; i < count; i++) {
      target[count - i - 1] = map(source[i]);
    }
  }
}
5reactions
davidje13commented, Aug 13, 2019

This seems backwards to me; it’s clear that “This condition will always return ‘false’” is a lie. In the example, it will return true!

The current <T extends unknown> behaviour is the correct one. The <T> behaviour is wrong.

Read more comments on GitHub >

github_iconTop Results From Across the Web

no-unnecessary-type-constraint - TypeScript ESLint
Disallow unnecessary constraints on generic types. ... Generic type parameters ( <T> ) in TypeScript may be "constrained" with an extends keyword.
Read more >
A complete guide to TypeScript's never type - Zhenghao
TypeScript's never type is very under-discussed, because it's not nearly as ubiquitous or inescapable as other types. A TypeScript beginner ...
Read more >
Typescript Generics Explained - Ross Bulat - Medium
T is constrained using the extends keyword followed by the type we are extending, within the angled brackets. Essentially, we are telling the...
Read more >
4. Functions - Programming TypeScript [Book] - O'Reilly
Besides function constructors (which you shouldn't use unless you are being ... type number , so using a generic T constrains the type...
Read more >
Is there a way to declare a type for a value that possibly ...
A specific type that "maybe, but not necessarily extends T " would, almost by necessity, become unknown . If a value of type...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found