ThomasReggi
ThomasReggi

Reputation: 59345

Type 'T' cannot be used to index type "Class"

I am looking to make a typescript generic of the Parameters for a specific class.

type Example<T> = Parameters<UserRepository[T]>[0]

However I get this error:

Type 'T' cannot be used to index type "UserRepository"

also tried this:

type Example<T extends string> = Parameters<UserRepository[T]>[0]

I currently have this:

type Params = Parameters<UserRepository["members"]>[0] & 
              Parameters<UserRepository["contacts"]>[0] & 
              Parameters<UserRepository["user"]>[0]

I would like to create two generics ClassMethod and ClassMethods.

type ClassMethod<C, M> = string
type Param = ClassMethod<UserRepository, 'members'>

Or

type ClassMethod<T> = Parameters<UserRepository[T]>[0]
type Param = ClassMethod<'members'> // where the generic has `UserRepository `in it.

And

type ClassMethods<C, M> = string
type Params = ClassMethods<UserRepository, ['members', 'contacts', 'user']>

Upvotes: 0

Views: 1860

Answers (1)

ThomasReggi
ThomasReggi

Reputation: 59345

ClassMethod<'meow'>

The first example is simple, the class is embeded in d

type ClassMethod<T extends keyof UserRepository> = Parameters<UserRepository[T]>[0]

ClassMethod<UserRepository, 'meow'>

type ClassMethod<c extends any, T extends keyof c> = Parameters<c[T]>[0]

ClassMethods<UserRepository, 'meow' | 'woof'>

class UserRepository {
    meow (i: { catSound: string }) {

    }
    woof (i: { dogSound: string }) {

    }
}

// As usual, see https://stackoverflow.com/questions/50374908/transform-union-type-to-intersection-type
type UnionToIntersection<U> = 
  (U extends any ? (k: U)=>void : never) extends ((k: infer I)=>void) ? I : never

type ClassMethods<C, M extends keyof C> = UnionToIntersection<{
    [K in M]: C[K] extends ((...args: any[]) => any) ? Parameters<C[K]>[0] : never
}[M]>

type Parms = ClassMethods<UserRepository, 'meow' | 'woof'>

// Or if you really want an array...
type ClassMethods2<C, M extends Array<keyof C>> = UnionToIntersection<{
    [K in M[number]]: C[K] extends ((...args: any[]) => any) ? Parameters<C[K]>[0] : never
}[M[number]]>

type Parms2 = ClassMethods2<UserRepository, ['meow', 'woof']>

Special thank you to Gerrit Birkeland on typescript gitter.

Upvotes: 1

Related Questions