Skip to content

Commit 47d664a

Browse files
merintheressamerin.mathew
andauthored
Explanation on how TypeScript handles conflicts between interfaces and intersection types (#3183)
Co-authored-by: merin.mathew <merin.mathew@onelogic.de>
1 parent 8f25f4f commit 47d664a

File tree

1 file changed

+33
-3
lines changed

1 file changed

+33
-3
lines changed

packages/documentation/copy/en/handbook-v2/Object Types.md

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -585,10 +585,40 @@ We just looked at two ways to combine types which are similar, but are actually
585585
With interfaces, we could use an `extends` clause to extend from other types, and we were able to do something similar with intersections and name the result with a type alias.
586586
The principal difference between the two is how conflicts are handled, and that difference is typically one of the main reasons why you'd pick one over the other between an interface and a type alias of an intersection type.
587587

588-
<!--
589-
For example, two types can declare the same property in an interface.
588+
If interfaces are defined with the same name, TypeScript will attempt to merge them if the properties are compatible. If the properties are not compatible (i.e., they have the same property name but different types), TypeScript will raise an error.
589+
590+
In the case of intersection types, properties with different types will be merged automatically. When the type is used later, TypeScript will expect the property to satisfy both types simultaneously, which may produce unexpected results.
591+
592+
For example, the following code will throw an error because the properties are incompatible:
593+
594+
```ts
595+
interface Person {
596+
name: string;
597+
}
598+
599+
interface Person {
600+
name: number;
601+
}
602+
```
603+
604+
In contrast, the following code will compile, but it results in a `never` type:
605+
606+
```ts twoslash
607+
interface Person1 {
608+
name: string;
609+
}
610+
611+
interface Person2 {
612+
name: number;
613+
}
590614

591-
TODO -->
615+
type Staff = Person1 & Person2
616+
617+
declare const staffer: Staff;
618+
staffer.name;
619+
// ^?
620+
```
621+
In this case, Staff would require the name property to be both a string and a number, which results in property being of type `never`.
592622

593623
## Generic Object Types
594624

0 commit comments

Comments
 (0)