Home > Net >  Typescript Partial interface odd behavior
Typescript Partial interface odd behavior

Time:08-30

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

  • Related