'Exclude property from type

I'd like to exclude a single property from the type. How can I do that?

For example I have

interface XYZ {
  x: number;
  y: number;
  z: number;
}

And I want to exclude property z to get

type XY = { x: number, y: number };


Solution 1:[1]

Omit ...

single property

type T1 = Omit<XYZ, "z"> // { x: number; y: number; }

multiple properties

type T2 = Omit<XYZ, "y" | "z"> // { x: number; } 

properties conditionally

e.g. all string types:

type Keys_StringExcluded<T> = 
  { [K in keyof T]: T[K] extends string ? never : K }[keyof T]

type XYZ = { x: number; y: string; z: number; }
type T3a = Pick<XYZ, Keys_StringExcluded<XYZ>> // { x: number; z: number; }

Shorter version with TS 4.1 key remapping / as clause in mapped types (PR):

type T3b = { [K in keyof XYZ as XYZ[K] extends string ? never : K]: XYZ[K] } 
// { x: number; z: number; }

properties by string pattern

e.g. exclude getters (props with 'get' string prefixes)

type OmitGet<T> = {[K in keyof T as K extends `get${infer _}` ? never : K]: T[K]}

type XYZ2 = { getA: number; b: string; getC: boolean; }
type T4 = OmitGet<XYZ2> //  { b: string; }

Note: Above template literal types are supported with TS 4.1. You can also write get${string} instead of get${infer _} here.

More infos

Pick, Omit and other utility types

How to Pick and rename certain keys using Typescript? (rename instead of exclude)

Playground

Solution 2:[2]

With typescript 2.8, you can use the new built-in Exclude type. The 2.8 release notes actually mention this in the section "Predefined conditional types":

Note: The Exclude type is a proper implementation of the Diff type suggested here. [...] We did not include the Omit type because it is trivially written as Pick<T, Exclude<keyof T, K>>.

Applying this to your example, type XY could be defined as:

type XY = Pick<XYZ, Exclude<keyof XYZ, "z">>

Solution 3:[3]

I've found solution with declaring some variables and using spread operator to infer type:

interface XYZ {
  x: number;
  y: number;
  z: number;
}

declare var { z, ...xy }: XYZ;

type XY = typeof xy; // { x: number; y: number; }

It works, but I would be glad to see a better solution.

Solution 4:[4]

In Typescript 3.5+:

interface TypographyProps {
    variant: string
    fontSize: number
}

type TypographyPropsMinusVariant = Omit<TypographyProps, "variant">

Solution 5:[5]

If you prefer to use a library, use ts-essentials.

import { Omit } from "ts-essentials";

type ComplexObject = {
  simple: number;
  nested: {
    a: string;
    array: [{ bar: number }];
  };
};

type SimplifiedComplexObject = Omit<ComplexObject, "nested">;

// Result:
// {
//  simple: number
// }

// if you want to Omit multiple properties just use union type:
type SimplifiedComplexObject = Omit<ComplexObject, "nested" | "simple">;

// Result:
// { } (empty type)

PS: You will find lots of other useful stuff there ;)

Solution 6:[6]

Typescript 3.5

As of Typescript 3.5, the Omit helper will be included: TypeScript 3.5 RC - The Omit Helper Type

You can use it directly, and you should remove your own definition of the Omit helper when updating.

Solution 7:[7]

I do like that:

interface XYZ {
  x: number;
  y: number;
  z: number;
}
const a:XYZ = {x:1, y:2, z:3};
const { x, y, ...last } = a;
const { z, ...firstTwo} = a;
console.log(firstTwo, last);

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Jason Hoetger
Solution 3 Qwertiy
Solution 4 CorayThan
Solution 5 Krzysztof Kaczor
Solution 6 GonchuB
Solution 7 Andrew Zolotarev