Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

In TypeScript, an intersection does not let the right-hand type override the left. A & B means a value must satisfy both types, so incompatible declarations for the same property can make that property never. To intentionally change a property, remove the original key with Omit and then add the replacement.

Why conflicting properties become never

An intersection combines requirements. If two object types both declare a property, a value of the resulting type must meet both declarations simultaneously. A value cannot ordinarily be both a string and a number, so the property has no usable value:

type Person1 = { name: string };
type Person2 = { name: number };
type Staff = Person1 & Person2;

// Staff requires name to be both string and number.
// The property type is never.

The right question is whether a real value should satisfy both constraints. If the intended value should have only one of the two property types, an intersection describes the wrong relationship. The TypeScript Handbook’s object types guide explains how intersections combine members.

Replace a property with Omit

When a new shape should retain the rest of a base type but redefine one property, exclude that key before adding its replacement:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
type ApiRecord = {
  id: string;
  value: number;
};

type DisplayRecord = Omit<ApiRecord, "value"> & {
  value: string;
};

DisplayRecord keeps id from ApiRecord and declares value as a string. Because the original value was removed first, there are no competing declarations to intersect. TypeScript’s utility types reference documents Omit.

Choose a union for alternative shapes

If a value can have one shape or another, use a union rather than an intersection. A literal discriminant gives TypeScript a reliable way to narrow the type:

Rank #2
TypeScript Programming Language - Software Engineer & Coder T-Shirt
  • TypeScript implements a superset of syntax for strictly typed development, facilitating deep static analysis and enhanced development environment integration. The compiler translates source into standard script formats, ensuring parity across any runtime.
  • TypeScript is ideal for front-end developers, full-stack engineers, and software architects who build large-scale web applications. It serves those looking to improve code excellence, reduce bugs through static checking, and maintain complex projects more.
  • Lightweight, Classic fit, Double-needle sleeve and bottom hem
type Circle = { kind: "circle"; radius: number };
type Square = { kind: "square"; sideLength: number };
type Shape = Circle | Square;

Here, a Shape is a circle or a square—not both. Checking kind lets TypeScript identify the relevant member. The Handbook’s narrowing guide covers discriminated unions.

Use interface extension when conflicts should be errors

Interface extension can be a better fit when declarations are intended to build on a shared contract and a conflicting property should be rejected immediately. Unlike an intersection, extending an interface with an incompatible same-name property produces an error instead of combining the property types into a potentially unusable result. See the Handbook’s object types guide for the distinction.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Account for TypeScript version differences

TypeScript 3.9 introduced stricter checks for intersections and documented that conflicting discriminant properties can reduce an impossible intersection to never as a whole. Depending on the conflict and compiler version, a diagnostic may therefore refer to a property on never, rather than simply displaying that property’s type as never. The TypeScript 3.9 release notes describe the change.

Pick the model that matches the intent

What you mean Use Why
A value must meet every requirement Intersection, A & B Every constituent constraint applies.
One property is intentionally redefined Omit<Base, "key"> & { key: NewType } Removes the original declaration before adding the new one.
A value may have one of several shapes Union, often with a discriminant Models alternatives and supports narrowing.
Declarations extend a shared contract and conflicts should fail Interface extension Incompatible extended properties are reported as errors.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.