#Is it possible to make a type param mandatory?

10 messages · Page 1 of 1 (latest)

slow dome
#
const something = <T extends string>(): string & { a: T } => {
  return 'a' as any;
};

something();
// ^ should force you to pass the type param

I need it to force the user to pass a string to something<'some string'>. Is that possible?

heady oracle
#

@slow dome No, and to be honest, if you need to require a type param it's probably not a good use of generics.

#

!:thats-no

fallen heronBOT
#
tjjfvi#0
`!tjjfvi:thats-no-generic-its-a-type-cast`:

When you use a type parameter in the function, it should generally be inferrable from the arguments.

For example, this is a misuse of generics:

function getMeA<T>(): T {
   /* magic */
}

because getMeA<string>() and getMeA<number>() compile to the same code at runtime, there's so way to implement this function safely (other than always throwing); this is just a type cast in disguise. Instead of using a generic here, you should return unknown, and cast at the call site if necessary, to be clear it's an unsafe operation:

-function getMeA<T>(): T {
+function getMeA(): unknown {
    /* magic */
 }

-getMeA<number>()
+getMeA() as number

One exception to this rule is if you're returning a possibly-empty container of T. For example, these are all perfectly safe, even though the generic can't be inferred from the parameters:

function emptyArray<T>(): Array<T> {
  return []
}

function useRef<T>(): { current?: T } {
  return {}
}
slow dome
#

I can see why it would generally be bad, but there isnt a better way to do nominal typing in TS

#

too bad but its not a big deal, thx for the help

heady oracle
#

@slow dome It's not necessary but you could take it the string at runtime

#
const something = <T extends string>(_str: T): string & { a: T } => {
  return 'a' as any;
};
slow dome
#

yeah that could work just feels kinda icky to pass in a runtime param to satisfy TS