2

I encountered a type declaration in the library react-router that is causing me a lot of trouble to understand:

export interface RouteComponentProps<
    Params extends { [K in keyof Params]?: string } = {},
    C extends StaticContext = StaticContext,
    S = H.LocationState
> {
    ...
}

The first line of the generics is the hardest for me. And I would love some help with this...

Params extends { [K in keyof Params]?: string } = {}

As far as I understand it, we are taking some interface called Params as an argument and then we make every element in that interface optional. So, we are manipulating the passed in interface.

I am also having a lot of trouble understanding the equal sign = {}. What does it mean to extend an interface and setting it equal to something? Thanks!

2
  • 1
    You're not "manipulating the passed in interface", but rather saying that whatever type you pass as that first type param must extend { [K in keyof Params]?: string }. The = {} is just providing a default value for that type parameter- so if you do not pass any type param, it'll default to {}. Commented Jan 13, 2020 at 22:47
  • Thanks for providing the answer! One small question: why is there a question mark behind [K in keyof Params]? - ? is this so the compiler wont complain when Params is empty? Commented Jan 13, 2020 at 22:52

1 Answer 1

3

Explanations of Params generic

Params extends { [K in keyof Params]?: string } = {}

It means that Params needs to be an object(key->value map) which can have all properties optional and all these properties will be type of string. {} means default type when we don't put the argument. I said properties can be, but not must be optional, as extends you can read as is assignable to, so for example object with all/some properties required will fit that requirement. Consider:

// function which has Params property
const f = <Params extends { [K in keyof Params]?: string } = {}>(p: Params) => p;
type A = {
    a: string // required field
}
f({ a: 'str' } as A) // is ok, pass the interface
type B = {
    b?: string // not required field
}
f({} as B) // is ok pass the interface

So really Params mean any object with string properties, no matter required or not. It means also that empty object {} can be used as we don't require any property to be there.

Explanation of other generic types

Next lines are rather simple:

C extends StaticContext = StaticContext

Type C needs to be assignable to type StaticContext, so needs to have all properties of StaticContext if we assume its an object

S = H.LocationState

Type S can be anything, but if will not be provided, will be as default H.LocationState

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.