'How to override type properties in TypeScript
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?
Solution 1:[1]
Create a helper type:
type Overwrite<T, U> = Pick<T, Exclude<keyof T, keyof U>> & U;
Usage:
type HexColorLine = Overwrite<Line, { color: number }>
Solution 2:[2]
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'/...
}
Solution 3:[3]
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}
Solution 4:[4]
A simple one off solution as of TypeScript 3.5 could be:
type HexColorLine = Omit<Line, 'color'> & {
color: number;
}
Solution 5:[5]
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.
Solution 6:[6]
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
.
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 | Maxim Mazurok |
Solution 2 | basarat |
Solution 3 | farukg |
Solution 4 | Pablo R. Dinella |
Solution 5 | |
Solution 6 | joshfarrant |