Home > front end >  Return default value of generic parameter
Return default value of generic parameter

Time:01-13

Coming from C#. How do we return default value of generic parameter in Typescript? For example here is an utterly useless function in C#:

private T TwiceAsMuch<T>(T number)
{
  if (number is int n)
    return (T)(object)(n * 2);
  else if (number is float f)
    return (T)(object)(f * 2);
  else
    return default;
}

How do I achieve this last line return default in Typescript?

Context

I'm writing a little wrapper function that performs axios.post and returns the response in the type specified by the caller:

private static async postInternal<T>(route: string, data: unknown): Promise<T> {
  await Vue.$axios.get('/sanctum/csrf-cookie')
  const res = await Vue.$axios.post<T>(`${route}`, data)
    .then(res => res.data)
    .catch(err => {
      openErr(err)
      return ???
    })
}

What goes in place of ????

CodePudding user response:

Sorry to say there is no equivalent. A value has a type, but a type may never have a value, default or otherwise.

I know nothing of C#, but according to this answer return default does this:

default keyword will return null for reference types and zero for numeric value types.

This pattern does not exist in Typescript. Unlike C#, Typescript transpiles to javascript. And javascript has no static typing. That means that at runtime, you cannot know the type of T. It's completely gone from the executing code.

This typescript:

postInternal<number>('/path', { data: true })

And this typescript:

postInternal<{ a: { b: { c: number } } }>('/path', { data: true })

Both compile to this javascript:

postInternal('/path', { data: true })

Which means the type of T cannot be known at runtime. Therefore you cannot branch your code path based on the type of T alone.


Typically the way you would handle this case is to allow the result to be nullable, and then just return null in the error case:

private static async postInternal<T>(route: string, data: unknown): Promise<T | null> {
  //...
}

const num = postInternal<number>('/path', { data: true }) ?? 0

Or by simply throwing the error and letting the caller catch it and handle what to do from there.

try {
  const num = postInternal<number>('/path', { data: true })
} catch (error) {
  console.error('exploded :(', error)
}
  •  Tags:  
  • Related