microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.72k stars 12.45k forks source link

ts2367 Comparing non-comparable types not detected with optional property #32627

Open junoatwork opened 5 years ago

junoatwork commented 5 years ago

TypeScript Version: 3.6.0-dev.20190730 (also with 3.5.1)

Search Terms: compare types, comparable, always false comparison, optional property, properties

Code

enum X {
  A= 'A'
}

function x(res: {action: string}):boolean {
  return res === X.A // error
}

function y(res: {action: string | undefined}):boolean {
  return res === X.A // error
}

function z(res: {action?: string}):boolean {
  return res === X.A // no error, but always false
}

function correct(res: {action: string}):boolean {
  return res.action === X.A // what the code should have been
}

Expected behavior:

The comparison in function z should have resulted in error TS2367: This condition will always return 'false' since the types '{ action?: string; }' and 'X.A' have no overlap.

Actual behavior:

Functions x, y give the correct error. Function z has no compiler error, but the condition will always evaluate to false since it is comparing an object and a string.

Playground Link: https://www.typescriptlang.org/play/#code/KYOwrgtgBAGlDeBYAUFNUCCBeKByDuKAviigGZggDGALgJYD2IUAHgBQBOwAzgFwIBDWoxD9uNDnRABzIgEpeAIwYMANsAHMkyLjTAdmXblCynYAOgxQA9NajAOHBh2KlkFavSZQAnpx788EJeolDikjJQAD5QlAAmwGRSwHHySirqmggouvqGPCZmMJY2dg5OLsgkyOSUwt4AXv58gvUgAPxiElKyCspqGlo5wHoGUEaFOMVWtlAgDPaOzgA0UIpgNFACqgDuAj7GZNvcwK417nUhUFTOXLTNgcEiXRG96QNZ2rljRuZP3qYpiVZjsABYCTY0UHAa4MBJhUEMMCqOJQcEANxhimAoDOQA

Related Issues: n/a

DanielRosenwasser commented 5 years ago

It's an interesting question as to whether or not comparability checks should actually be exempt from weak type checks. I'm usually pretty conservative on this stuff, but my intuition tells me this would not break that much.

haymez commented 2 years ago

I recently ran across some broken code in a repo that lead me here. Basically my situation was something like the following:

interface Car {
  make: string
  model: string
}

type SomeType = Partial<Car>

const car: SomeType = {}

if (car === "typescript doesn't complain about this") {
    // This code will never execute..?
}

Weak typing is clearly giving us a false sense of security about this code by not warning us that there's no overlap between the partial type and a string. Would love for Typescript to detect these types of errors in the future.