Как исключить ключ из интерфейса в TypeScript
В TypeScript вы можете объединить два типа интерфейса, например
interface Foo {
var1: string
}
interface Bar {
var2: string
}
type Combined = Foo & Bar
Вместо сочетания клавиш я хочу исключить ключи из одного интерфейса в другой. В любом случае вы можете сделать это в 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}
/>
)
}
}
С этим я могу написать
const ValuedComponent = valueHOC(MyComponent)
затем
<ValuedComponent />
но проблема в том, что возвращаемый тип компонента также использует тип реквизита из данного компонента, поэтому TypeScript будет жаловаться и попросить меня предоставить поддержку value
. В результате мне придется написать что-то вроде
<ValuedComponent value="foo" />
Какое значение в любом случае не будет использоваться. Я хочу здесь вернуть интерфейс без определенных ключей, я хочу иметь что-то вроде этого
React.ComponentClass<P - {value: string}>
Тогда value
не потребуется в возвращаемом компоненте. Возможно ли это в TypeScript?
Ответы
Ответ 1
В 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: ''
};
Так что в связи с вашим вопросом может быть то, что вы хотите:
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}
/>
)
}
}
Ответ 2
Существует библиотека типов утилит с отображенным типом 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; }
Ответ 3
Вы не можете удалить свойства из уже существующих интерфейсов. Даже попытка расширить существующий интерфейс с интерфейсом, имеющим свойство value
, заданное как необязательное, вернет ошибку.
Чтобы избежать этой проблемы, измените типичность целевого компонента, поэтому свойство value
не является обязательным.
например.
// ...
class MyComponent extends React.Component<{value?: string}, State> {
// ...
}
а затем компонент, созданный при использовании функции высокого порядка
const valuedComponent = valueHOC(MyComponent);
не будет запрашивать value
prop.