1

Problem

Let's say I have an interface Wrapped:

interface Wrapped<T> {
  data: T
}

And I want to define a function like this:

function f<T>(arg: any): T {
  const obj: Wrapped<T> = doSomethingAndGetWrappedObject<T>(arg)
  return obj.data
}

// Don't pay attention to the argument, it is not important for the question
const n: number = f<number>(/* ... */)

The problem is, in my application it is very inconvenient to pass number as type argument, I would like to pass Wrapped<number> instead, i.e. to call f like this:

const n: number = f<Wrapped<number>>(/* ... */)

The question is: how to type f to make it possible?

What I've tried

function f<T extends Wrapped<V>, V>(arg: any) {
  // ...
}
// Now this works, but it is very annoying to write the second type argument
const n: number = f<Wrapped<number>, number>() 
// I would like to do this, but it produces an error
// Typescript accepts either no type arguments or all of them
const n: number = f<Wrapped<number>>()
// This just works in an unpredictable way
function f<T extends Wrapped<any>>(
  arg: any
): T extends Wrapped<infer V> ? V : any {
  /* ... */
}
1

1 Answer 1

2

You could create helper type for extracting the generic type by using infer keyword.

interface Wrapped<T> {
  data: T
}

type ExtractGeneric<T> = T extends Wrapped<infer X> ? X : never

function f<T extends Wrapped<any>>(): ExtractGeneric<T> {
  ....
}

const n = f<Wrapped<number>>()
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.