我想定义一个ExcludeCart<T>基本类型,T但要cart删除给定键(在我的情况下为)的通用类型。所以,举例来说,ExcludeCart<{foo: number, bar: string, cart: number}>将是{foo: number, bar: string}。有没有办法在TypeScript中做到这一点?
ExcludeCart<T>
T
cart
ExcludeCart<{foo: number, bar: string, cart: number}>
{foo: number, bar: string}
这就是为什么我要这样做的原因,以防万一我把错误的树叫了起来:我正在将现有的JavaScript代码库转换为TypeScript,其中包含一个称为Decor的装饰器函数,该函数cartify接受React组件类Inner并返回另一个组件类Wrapper。
cartify
Inner
Wrapper
Inner应该带一个cart道具,以及零个或多个其他道具。Wrapper接受cartClient道具(用于生成cart要传递给的道具Inner),以及Inner接受的任何道具( 除外) cart。
cartClient
换句话说,一旦我想出了如何定义ExcludeCart,就可以使用它来做到这一点:
ExcludeCart
function cartify<P extends {cart: any}>(Inner: ComponentClass<P>) : ComponentClass<ExcludeCart<P> & {cartClient: any}>
虽然没有内置的减法类型,但是您现在可以将其入侵:
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>>
在操场上测试