如何从TypeScript中的接口中排除键

Fan*_*Lin 19 typescript

在TypeScript中,您可以组合两种类型的接口类型

interface Foo {
    var1: string
}

interface Bar {
    var2: string
}

type Combined = Foo & Bar
Run Code Online (Sandbox Code Playgroud)

我想要将键从一个接口排除到另一个接口,而不是组合键.无论如何你可以在TypeScript中做到吗?

原因是,我有一个HOC,它管理其他包装组件的属性值

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}
        />
      )
    }
}
Run Code Online (Sandbox Code Playgroud)

有了这个,我可以写

const ValuedComponent = valueHOC(MyComponent)
Run Code Online (Sandbox Code Playgroud)

然后

<ValuedComponent />
Run Code Online (Sandbox Code Playgroud)

但问题是,返回的组件类型也使用来自给定组件的props类型,因此TypeScript会抱怨并要求我提供value道具.结果,我将不得不写一些类似的东西

<ValuedComponent value="foo" />
Run Code Online (Sandbox Code Playgroud)

无论如何都不会使用哪个值.我想要的是返回没有特定键的接口,我希望有这样的东西

React.ComponentClass<P - {value: string}>
Run Code Online (Sandbox Code Playgroud)

然后value在返回的组件中将不需要.现在可以在TypeScript中使用吗?

AJP*_*AJP 24

在TypeScript 2.8中,您现在可以执行以下操作:

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: ''
};
Run Code Online (Sandbox Code Playgroud)

因此,就您的问题而言,以下可能是您想要的:

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}
        />
      )
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 在执行此操作的同时,它将使可选参数成为必需。您可以这样做来防止这种情况:/sf/answers/3375120731/ (3认同)

ilo*_*ett 19

interface MyDialogProps extends Omit<DialogProps, 'onClose'> {
  id: string;
  onClose: (reason: string) => void;
}

export const MyDialog: React.FC<MyDialogProps> = ({ id, onClose, ...props) => (
  <Dialog onClose={() => onClose("whatever")} {...props} />
);
Run Code Online (Sandbox Code Playgroud)

  • 这应该是接受者的答案,以及法比奥的答案。接受的答案创建一个类型而不是接口! (2认同)

Fab*_*lho 14

仅使用“省略”几个属性的示例interface

interface ABC {
    a: string;
    b: string;
    c: string;
}

type PropsABCOmitted = 'a' | 'c';
interface BD extends Omit<ABC, PropsABCOmitted> {
    d: string;
}

// instance example of interface BD:
const test: BD = {
    b: 'b',
    d: 'c'
};
Run Code Online (Sandbox Code Playgroud)


Chi*_*tsu 7

有一个具有映射类型的实用程序类型库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; }
Run Code Online (Sandbox Code Playgroud)