I ran across some code that looked completely wrong in a repo I'm working on. Below is an example of what I came across.
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..?
}
Am I missing something? car
will never be equal to a string, right? Normally when you try to compare two different types that have no overlap Typescript will yell at you and tell you it will always return false. Any help on this would be greatly appreciated!
CodePudding user response:
Partial<Car>
is a weak type because all its properties are optional. TypeScript 2.4 added a check that would warn you if you tried to assign something like a string
to a weak type, since there are no overlapping properties:
let car: { make?: string, model?: string };
car = {}; // okay
car = "oops"; // error! Type '"oops"' has no properties in common with type
// '{ make?: string | undefined; model?: string | undefined; }'.
But before TypeScript 2.4, car = "oops"
would have been allowed with no error, because none of the apparent members of "oops"
(like length
and toUpperCase
) conflict with Partial<Car>
. Structurally speaking, a string
is a Partial<Car>
. But the assignment is probably an mistake and weak type detection warns you about it.
This weak type detection only seems to apply to assignability, though. It doesn't kick in for comparison operators, as you've noticed:
if (car === "oops") { } // no error
There is an open feature request at microsoft/TypeScript#32627 asking for this to be changed. If you care enough about this to see it changed, you might go to that issue, give it a