Home > Mobile >  What difference between extends and = in generic types?
What difference between extends and = in generic types?

Time:03-17

What difference between these two functions? Both work the same. I know how extends work in interfaces but I can't understand the differences here

const func = <T extends string>(str: T): T => str 
const func = <T = string>(str: T): T => str 

CodePudding user response:

These are very different things.


<T extends string>

This is a constraint. This means that T must be string or a subtype of string (i.e. a string literal)

const func = <T extends string>(str: T): T => str

func("A") // returns type "A" because "A" is a subtype of string
func<string>("A") // returns type string because the inference was overridden
func(123) // error 123 is not a subtype of string

Playground


<T = string>

This is a default type. In this case T is not constrained, but if omitted string is used as the type of T.

const func = <T = string>(str: T): T => str

func("A") // returns type "A" because "A" is a inferred for T
func<string>("A") // returns type string because the inference was overridden
func(123) // returns type 123 because 123 is inferred as the type for T

Playground

The default type doesn't make a lot of sense in this example though since it is inferred by the argument when you omit it. So lets look at a different example:

type MyType<T = string> = { value: T }
type TestA = MyType<number> // equivalent to { value: number }
type TestB = MyType // equivalent to { value: string }

Playground

Note how in TestB you can leave out the generic, and the default of string is used instead.

However, in the case of T extends string both TestA and TestB are type errors:

type MyType<T extends string> = { value: T }
type TestA = MyType<number> // type error: number does not extend string
type TestB = MyType // type error: missing generic parameter

Playground

  • Related