41

For example, I have

type Line = {
  start: Point;
  end: Point;
  color: string; //'cyan'/'aquablue'/...
}

But now I want to create new line type on the base of Line, so that it stores color as number:

type HexColorLine = Point & {
  color: number;
}

Now I expect the HexColorPoint type be equal to

{
  start: Point;
  end: Point;
  color: number;
}

But it equals to

{
  start: Point;
  end: Point;
  color: string | number;
}

Is there a way to override but not extend the prop type with some short syntax? Do i really have to define entirely new type for this?

2

8 Answers 8

78

Create a helper type:

type Overwrite<T, U> = Pick<T, Exclude<keyof T, keyof U>> & U;

Usage:

type HexColorLine = Overwrite<Line, { color: number }>
Sign up to request clarification or add additional context in comments.

3 Comments

Is this still valid for TypeScript v3.9?
This can be written today as type Overwrite<T, U> = Omit<T, keyof U> & U;
I have a problem with that solution: it lets me add arbitrary properties. I want to have an error of I'm overwriting a property name that doesn't exist...
25

A simple one off solution as of TypeScript 3.5 could be:

type HexColorLine = Omit<Line, 'color'> & {
  color: number;
}

Comments

15

In TypeScript 3.5 or later you can use Omit<Type, Keys>.

For types:

type HexColorPoint = Omit<Line, "color"> & {
    color: number;
}

For interfaces:

interface HexColorPoint extends Omit<Line, "color"> {
    color: number;
}

Comments

9

To expand on Pablo's answer which uses Omit, you can do the following to make a more generic utility type.

type Overwrite<Base, Overrides> = Omit<Base, keyof Overrides> & Overrides


type HexColorLine = Overwrite<Line, { color: number }>

This omits all of the keys in the provided Overrides type from the Base type, then combines that with the provided Overrides.

Comments

6

This is not supported at the moment. TypeScript would need a concept of subtraction types. Proposals exist https://github.com/Microsoft/TypeScript/issues/12215 and https://github.com/Microsoft/TypeScript/issues/4183

Fix

Create a base type :

type LineBase = {
  start: Point;
  end: Point;
}
type LineBase = LineBase & {
  color: string; //'cyan'/'aquablue'/...
}

1 Comment

Thanks, this helped! I had type where I needed to narrow the type on a property and this works.
4

TL;DR:

type Omit<T, K> = Pick<T, Exclude<keyof T, K>>
type Override<T, U> = Omit<T, keyof U> & U

type ColorNumber =  {
  color: number;
}

type HexColorPoint = Override<
  Line,
  ColorNumber
> // --> {start: Point; end: Point; color: number}

I assume you wanted to do

type HexColorLine = Line & {
  color: number;
}

instead of

type HexColorLine = Point /* <-- typo? */ & {
  color: number;
}

With Typescript >2.8 i was able to override like this:

From https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-8.html :

We did not include the Omit type because it is trivially written as Pick<T, Exclude<keyof T, K>>.

// So we define Omit -.-
type Omit<T, K> = Pick<T, Exclude<keyof T, K>>

// Sidenote: 
// keyof is just getting all the keys for a given type separeted by |
// keyof Line --> 'start' | 'end' | 'color'

// And we define Override which unions the type without unwanted keys and the 
// type defining the new keys
type Override<T, U> = Omit<T, keyof U> & U

// just define which properties you want to redefine 
// and remove "Point &" as it will be done in the Override type
type HexColorLine =  {
  color: number;
}
type HexColorPoint = Override<
  Line,
  HexColorLine
> // --> {start: Point; end: Point; color: number}

Comments

2

You can try Override from the utility-types package https://github.com/piotrwitek/utility-types#overwritet-u. So in the future maybe you would like to use other cool helpers from there.

Comments

2

Every other answer in this thread makes ugly tooltips, here is one that doesn't

export type Overwrite<T, R> = { [K in keyof T]: K extends keyof R ? R[K] : T[K] };

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.