How to exclude a key from an interface in TypeScript
In TypeScript, you can combine two types of interface, for example
interface Foo {
var1: string
}
interface Bar {
var2: string
}
type Combined = Foo & Bar
Instead of a keyboard shortcut, I want to exclude keys from one interface to another. Is there anyway you can do this in TypeScript?
The reason is that I have a HOC that manages the property value for another wrapped component like
export default function valueHOC<P> (
Comp: React.ComponentClass<P> | React.StatelessComponent<P>
): React.ComponentClass<P> {
return class WrappedComponent extends React.Component<P, State> {
render () {
return (
<Comp
{...this.props}
value={this.state.value}
/>
)
}
}
With this I can write
const ValuedComponent = valueHOC(MyComponent)
then
<ValuedComponent />
but the problem is that the return type of the component also uses the props type from the given component, so TypeScript will complain and ask me for support value
. As a result, I will have to write something like
<ValuedComponent value="foo" />
Which value will not be used anyway. I want to return an interface here without specific keys, I want to have something like this
React.ComponentClass<P - {value: string}>
Then value
not needed in the returned component. Is this possible in TypeScript?
source to share
In TypeScript 2.8, you can now do the following:
interface Foo {
attribute1: string;
optional2?: string;
excludePlease: string;
}
// Define Omit. Can be defined in a utilities package
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
// Use Omit to exclude one or more fields (use "excludePlease"|"field2"|"field3" etc to exclude multiple)
type Bar = Omit<Foo, "excludePlease">
const b: Bar = {
attribute1: ''
};
So in relation to your question might be what you want:
export default function valueHOC<P> (
Comp: React.ComponentClass<P> | React.StatelessComponent<P>
): React.ComponentClass<Omit<P, "value">> {
return class WrappedComponent extends React.Component<Omit<P, "value">, State> {
render () {
return (
<Comp
{...this.props}
value={this.state.value}
/>
)
}
}
source to share
There is a utility type library with a mapped type Subtract
:
import { Subtract } from 'utility-types';
type Props = { name: string; age: number; visible: boolean };
type DefaultProps = { age: number };
type RequiredProps = Subtract<Props, DefaultProps>;
// Expect: { name: string; visible: boolean; }
source to share
You cannot remove properties from pre-existing interfaces. Even trying to extend an existing interface with an interface that has an value
optional property will return an error.
To avoid this problem, change the typicality of the target component, so the property value
is optional.
eg.
// ...
class MyComponent extends React.Component<{value?: string}, State> {
// ...
}
and then the component created when using the high order function
const valuedComponent = valueHOC(MyComponent);
will not ask for value
prop.
source to share