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?

+18


source to share


3 answers


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}
        />
      )
    }
}

      

+23


source


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; }

      

+1


source


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.

0


source







All Articles