admin管理员组

文章数量:1296493

I have a function that has 1-3 options where each option consists of generic types. I want to change this functionality so that it can take from 0-infinite amount of these pairs:

type CreateOpts<Type extends string, T> = {
  type: Type;
  things: Array<T>
};

type MyOptions<
  TType1 extends string = string,
  T1 = any,
  TType2 extends string = string,
  T2 = any,
  TType3 extends string = string,
  T3 = any
> = {
  opts: Readonly<
  | [
       CreateOpts<TType1, T1>,
    ]
  | [
       CreateOpts<TType1, T1>,
       CreateOpts<TType2, T2>,
    ]
  | [
       CreateOpts<TType1, T1>,
       CreateOpts<TType2, T2>,
       CreateOpts<TType3, T3>,
    ]
  >;
};

function myFunc<TType1 extends string, T1, TType2 extends string, T2, TType3 extends string, T3>(
  options: MyOptions<TType1, T1, TType2, T2, TType3, T3>
) {
  for(const thing of options.things) {
    console.log(things);
  }
}

How can I make it so I can pass there any number of "tuples" with generics?

I have a function that has 1-3 options where each option consists of generic types. I want to change this functionality so that it can take from 0-infinite amount of these pairs:

type CreateOpts<Type extends string, T> = {
  type: Type;
  things: Array<T>
};

type MyOptions<
  TType1 extends string = string,
  T1 = any,
  TType2 extends string = string,
  T2 = any,
  TType3 extends string = string,
  T3 = any
> = {
  opts: Readonly<
  | [
       CreateOpts<TType1, T1>,
    ]
  | [
       CreateOpts<TType1, T1>,
       CreateOpts<TType2, T2>,
    ]
  | [
       CreateOpts<TType1, T1>,
       CreateOpts<TType2, T2>,
       CreateOpts<TType3, T3>,
    ]
  >;
};

function myFunc<TType1 extends string, T1, TType2 extends string, T2, TType3 extends string, T3>(
  options: MyOptions<TType1, T1, TType2, T2, TType3, T3>
) {
  for(const thing of options.things) {
    console.log(things);
  }
}

How can I make it so I can pass there any number of "tuples" with generics?

Share Improve this question edited Feb 12 at 10:47 drodil asked Feb 12 at 10:46 drodildrodil 2,3461 gold badge23 silver badges43 bronze badges 1
  • I've simplified the solution – Alexander Nenashev Commented Feb 12 at 12:33
Add a comment  | 

1 Answer 1

Reset to default 0

You could use a function factory to type the function body with tuples as parameters for CreateOps:

Playground

type CreateOpts<Type extends string, T> = {
  type: Type;
  things: Array<T>
};

type OptionParams<Type extends string, T> = [Type, T];

function myFuncMaker<
  P extends OptionParams<string, any>  
>(
  cb: (option: Readonly<P extends OptionParams<infer A, infer B> ? CreateOpts<A, B> : never>) => void
){
  return cb;
}

const myFunc1 = myFuncMaker<['type', number] | ['type2', string]>(option => {

  if(option.type === 'type') {
    for(const thing of option.things){
      console.log(thing); // number
    }
  }

});

myFunc1({
  type: 'type',
  things: [1,2,3]
})

myFunc1({
  type: 'type2',
  things:['asdf', 'asdf', 'asdf']
})

myFunc1({
  type: 'type2',
  things:[1, 2, 3] // error
})

本文标签: typescriptInfinite number of generic pairsStack Overflow