可选地扩展typescript中类型的道具?

可选地扩展typescript中类型的道具?,typescript,Typescript,考虑下一个例子: enum Keys { A = 'a', B = 'b', C = 'c', } //imagine a lot more possible keys type ExtendKeysPropsByKey = { [Keys.A]: { a: string } [Keys.B]: { b: string } } //Keys.C doesn't require extended props type KeysPropsByKey =

考虑下一个例子:

enum Keys {
  A = 'a',
  B = 'b',
  C = 'c',
}
//imagine a lot more possible keys

type ExtendKeysPropsByKey = {
  [Keys.A]: {
    a: string
  }
  [Keys.B]: {
    b: string
  }
}
//Keys.C doesn't require extended props

type KeysPropsByKey = {
  [key in keyof Keys]: {
    key: key
  } & ExtendKeysPropsByKey[key]
  //errors: Type 'key' cannot be used to index type 'ExtendKeysPropsByKey'.
  //also tried:
  //ExtendKeysPropsByKey[key] ? ExtendKeysPropsByKey[key] : {}
  //ExtendKeysPropsByKey[key] || {}
  //key in keyof ExtendKeysPropsByKey ? ExtendKeysPropsByKey[key] : {}
  //neither works
}
因此,假设有50个可能的
,我们希望创建一个类型,该类型最初包含一个实际值为
道具,并且希望能够选择性地扩展道具,因此上述示例的预期类型为:

{
  [Keys.A]: {
    key: Keys.A
    a: string
  }
  [Keys.B]: {
    key: Keys.B
    b: string
  }
  [Keys.C]: {
    key: Keys.C
  }
}

有什么可能的情况吗?

我希望我能得到你想要的:)。所以我制作了一个带有两个参数的类型构造函数-
Keys
-它定义了我们将拥有的键,
KeyProps
-类型表示给定键应该拥有的属性

enum Keys {
  A = 'a',
  B = 'b',
  C = 'c',
}

type ExtendKeysPropsByKey = {
  [Keys.A]: {
    a: string
  }
  [Keys.B]: {
    b: string,
    c: number;
  }
}

type MakeT<Keys extends string, KeyProps extends Partial<Record<Keys, any>>> = {
  [K in Keys]: {key: K} & (K extends keyof KeyProps ? KeyProps[K] : {})
}

type Result = MakeT<Keys, ExtendKeysPropsByKey>
/**
type Result = {
    a: {
        key: Keys.A;
    } & {
        a: string;
    };
    b: {
        key: Keys.B;
    } & {
        b: string;
        c: number;
    };
    c: {
        key: Keys.C;
    };
}
*/
枚举键{
A=‘A’,
B=‘B’,
C=‘C’,
}
类型ExtendKeysPropsByKey={
[钥匙A]:{
a:字符串
}
[钥匙B]:{
b:绳子,
c:数字;
}
}
类型市场={
[K in Keys]:{key:K}&(K扩展KeyProps的KeyProps?KeyProps[K]:{})
}
类型结果=市场
/**
类型结果={
a:{
钥匙:钥匙A;
} & {
a:弦;
};
b:{
钥匙:钥匙B;
} & {
b:弦;
c:数字;
};
c:{
键:键C;
};
}
*/
说明:

  • KeyProps扩展了Partial
    我们将第二个参数定义为带有我们想要的键的记录,但它也是Partial的,因为不是我们需要的所有键
  • {key:K}&(K扩展KeyProps的KeyProps?KeyProps[K]:{})
    我们说我们在给定键上的值将具有属性
    key
    等于我们的键,并且我们将它与
    KeyProps
    对象中给定的属性相交

    • 我希望我能得到你想要的:)。所以我制作了一个带有两个参数的类型构造函数-
      Keys
      -它定义了我们将拥有的键,
      KeyProps
      -类型表示给定键应该拥有的属性

      enum Keys {
        A = 'a',
        B = 'b',
        C = 'c',
      }
      
      type ExtendKeysPropsByKey = {
        [Keys.A]: {
          a: string
        }
        [Keys.B]: {
          b: string,
          c: number;
        }
      }
      
      type MakeT<Keys extends string, KeyProps extends Partial<Record<Keys, any>>> = {
        [K in Keys]: {key: K} & (K extends keyof KeyProps ? KeyProps[K] : {})
      }
      
      type Result = MakeT<Keys, ExtendKeysPropsByKey>
      /**
      type Result = {
          a: {
              key: Keys.A;
          } & {
              a: string;
          };
          b: {
              key: Keys.B;
          } & {
              b: string;
              c: number;
          };
          c: {
              key: Keys.C;
          };
      }
      */
      
      枚举键{
      A=‘A’,
      B=‘B’,
      C=‘C’,
      }
      类型ExtendKeysPropsByKey={
      [钥匙A]:{
      a:字符串
      }
      [钥匙B]:{
      b:绳子,
      c:数字;
      }
      }
      类型市场={
      [K in Keys]:{key:K}&(K扩展KeyProps的KeyProps?KeyProps[K]:{})
      }
      类型结果=市场
      /**
      类型结果={
      a:{
      钥匙:钥匙A;
      } & {
      a:弦;
      };
      b:{
      钥匙:钥匙B;
      } & {
      b:弦;
      c:数字;
      };
      c:{
      键:键C;
      };
      }
      */
      
      说明:

      • KeyProps扩展了Partial
        我们将第二个参数定义为带有我们想要的键的记录,但它也是Partial的,因为不是我们需要的所有键
      • {key:K}&(K扩展KeyProps的KeyProps?KeyProps[K]:{})
        我们说我们在给定键上的值将具有属性
        key
        等于我们的键,并且我们将它与
        KeyProps
        对象中给定的属性相交