小编典典

TypeScript:从类型/减法类型中删除键

reactjs

我想定义一个ExcludeCart<T>基本类型,T但要cart删除给定键(在我的情况下为)的通用类型。所以,举例来说,ExcludeCart<{foo: number, bar: string, cart: number}>将是{foo: number, bar: string}。有没有办法在TypeScript中做到这一点?

这就是为什么我要这样做的原因,以防万一我把错误的树叫了起来:我正在将现有的JavaScript代码库转换为TypeScript,其中包含一个称为Decor的装饰器函数,该函数cartify接受React组件类Inner并返回另一个组件类Wrapper

Inner应该带一个cart道具,以及零个或多个其他道具。Wrapper接受cartClient道具(用于生成cart要传递给的道具Inner),以及Inner接受的任何道具(
除外) cart

换句话说,一旦我想出了如何定义ExcludeCart,就可以使用它来做到这一点:

function cartify<P extends {cart: any}>(Inner: ComponentClass<P>) : ComponentClass<ExcludeCart<P> & {cartClient: any}>

阅读 484

收藏
2020-07-22

共1个答案

小编典典

虽然没有内置的减法类型,但是您现在可以将其入侵:

type Sub0<
    O extends string,
    D extends string,
> = {[K in O]: (Record<D, never> & Record<string, K>)[K]}

type Sub<
    O extends string,
    D extends string,
    // issue 16018
    Foo extends Sub0<O, D> = Sub0<O, D>
> = Foo[O]

type Omit<
    O,
    D extends string,
    // issue 16018
    Foo extends Sub0<keyof O, D> = Sub0<keyof O, D>
> = Pick<O, Foo[keyof O]>

在问题的情况下,您可以执行以下操作:

type ExcludeCart<T> = Omit<T, 'cart'>

使用TypeScript> = 2.6,可以将其简化为:

/**
 * for literal unions
 * @example Sub<'Y' | 'X', 'X'> // === 'Y'
 */
export type Sub<
    O extends string,
    D extends string
    > = {[K in O]: (Record<D, never> & Record<string, K>)[K]}[O]

/**
 * Remove the keys represented by the string union type D from the object type O.
 *
 * @example Omit<{a: number, b: string}, 'a'> // === {b: string}
 * @example Omit<{a: number, b: string}, keyof {a: number}> // === {b: string}
 */
export type Omit<O, D extends string> = Pick<O, Sub<keyof O, D>>

在操场上测试

2020-07-22