typescript 如何有条件地从多个选项( prop )中只输入一个选项

jtw3ybtb  于 2022-12-27  发布在  TypeScript
关注(0)|答案(2)|浏览(183)

我有一个 prop 看起来像:

  1. {
  2. option1,
  3. option2,
  4. option3,
  5. option4,
  6. general,
  7. otheprops
  8. }

我想要的是使它只有一个选项可以使用在给定的时间我有什么作为类型:

  1. interface MyTypes {
  2. option1: boolean
  3. option2: boolean
  4. option3: boolean
  5. general: boolean
  6. otherprops: string
  7. }

我想做的是:

  1. interface GeneralTypes{
  2. general: boolean
  3. otherprops: string
  4. }
  5. interface Option1Types{
  6. option1: boolean
  7. }
  8. interface Option2Types{
  9. option2: boolean
  10. }
  11. interface Option3Types{
  12. option3: boolean
  13. }
  14. type MyTypes = GeneralTypes & ( Option1Types | Option2Types |Option3Types )

但我得到这个错误

  1. Property 'option1' does not exist on type '(GeneralTypes & Option1) | (GeneralTypes & Option2)| (GeneralTypes & Option3) '
  2. Property 'option2' does not exist on type '(GeneralTypes & Option1) | (GeneralTypes & Option2)| (GeneralTypes & Option3) '
  3. Property 'option3' does not exist on type '(GeneralTypes & Option1) | (GeneralTypes & Option2)| (GeneralTypes & Option3) '
az31mfrm

az31mfrm1#

下面是我在只需要设置其中一个属性时的发现。

  1. type RequireOnlyOne<T, Keys extends keyof T = keyof T> =
  2. Pick<T, Exclude<keyof T, Keys>>
  3. & {
  4. [K in Keys]-?:
  5. Required<Pick<T, K>>
  6. & Partial<Record<Exclude<Keys, K>, undefined>>
  7. }[Keys]
  8. interface GeneralTypes {
  9. general: boolean
  10. otherprops: string
  11. }
  12. type MyTypes = GeneralTypes & RequireOnlyOne<{
  13. option1: boolean,
  14. option2: boolean,
  15. option3: boolean,
  16. }>
  17. const props: MyTypes = {
  18. general: false,
  19. otherprops: '',
  20. option1: true,
  21. }

有一个完整的解释here

展开查看全部
yzuktlbb

yzuktlbb2#

  1. type UnionToIntersection<U> =
  2. (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never
  3. type DistinctUnion<T> =
  4. | UnionToIntersection<T> extends infer X ? ( // save to var X
  5. T extends any ? // split by '|'
  6. T & { [k in Exclude<keyof X, keyof T>]?: never } // add missing keys as ?:never
  7. : never
  8. ) : never
  9. type x = DistinctUnion<MyTypes>
  10. // type x = (GeneralTypes & Option1Types & {
  11. // option2: never;
  12. // option3: never;
  13. // }) | (GeneralTypes & Option2Types & {
  14. // option1: never;
  15. // option3: never;
  16. // }) | (GeneralTypes & ... 1 more ... & {
  17. // ...;
  18. // })
  19. declare let a: x;
  20. if (a.option1) {
  21. a; // GeneralTypes & Option1Types
  22. }
展开查看全部

相关问题