Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript: how to extract the generic parameter from a type?

Tags:

typescript

Say I have a type like React.ComponentClass<Props> and I want to reference the Props part but it is unnamed in my current context.

To illustrate:

const x = makeComponent(); // typeof x = React.ComponentClass<Something>

In this situation, I can use typeof x but that doesn't give me direct access to the Something type.

What I want is something like this:

type GetPropsType<C extends React.ComponentClass<P>> = P

So that I can extract Something with the type GetPropsType<typeof x>

Anything equivalent would be great.

like image 845
d.j.sheldrick Avatar asked Jun 30 '17 16:06

d.j.sheldrick


People also ask

How do you pass a generic type as parameter TypeScript?

Assigning Generic ParametersBy passing in the type with the <number> code, you are explicitly letting TypeScript know that you want the generic type parameter T of the identity function to be of type number . This will enforce the number type as the argument and the return value.

How do you define a generic type in TypeScript?

Generics allow creating 'type variables' which can be used to create classes, functions & type aliases that don't need to explicitly define the types that they use. Generics makes it easier to write reusable code.

Is generic type parameter?

Generic MethodsA type parameter, also known as a type variable, is an identifier that specifies a generic type name. The type parameters can be used to declare the return type and act as placeholders for the types of the arguments passed to the generic method, which are known as actual type arguments.

How do I use generic classes in TypeScript?

TypeScript supports generic classes. The generic type parameter is specified in angle brackets after the name of the class. A generic class can have generic fields (member variables) or methods. In the above example, we created a generic class named KeyValuePair with a type variable in the angle brackets <T, U> .


2 Answers

You can use infer:

type TypeWithGeneric<T> = T[]
type extractGeneric<Type> = Type extends TypeWithGeneric<infer X> ? X : never

type extracted = extractGeneric<TypeWithGeneric<number>>
// extracted === number

Playground

like image 152
Xiv Avatar answered Oct 24 '22 04:10

Xiv


You can use pattern matching for that:

namespace React {
    export class ComponentClass<T> {}
}

function doSomethingWithProps<T>(x : React.ComponentClass<T>) : T {
    return null as T;
}

class Something {}
let comp = new React.ComponentClass<Something>();
const instanceOfSomething = doSomethingWithProps(comp);
like image 25
Tamas Hegedus Avatar answered Oct 24 '22 05:10

Tamas Hegedus