1

I am creating a custom Type that should pick a generic's T object keys Key which type of T[Key] is number.

The code works but I want to make the error message clearer.

type KeysOfTypeNumber<T> = { [Key in keyof T]: T[Key] extends number ? Key : never }[keyof T]

type Keys = {
    currentPage: number
    prevPage: number
    searchParam: string
}

const passNumberKeys = <T>(numberTypeKeys: KeysOfTypeNumber<T>) => {
    console.log(numberTypeKeys)
}

passNumberKeys<Keys>('currentPage') // OK
passNumberKeys<Keys>('searchParam') // Type '"searchParam"' is not assignable to type 'KeysOfTypeNumber<Keys>'

A working code sample is here

Is it possible to fix my custom type so it throws something at least like Type '"searchParam"' is not assignable to type 'Argument must be of type number inside the generic'.

Already tried to follow this example, but the error remains the same.

2
  • 1
    Wouldn't you prefer Type '"searchParam"' is not assignable to type '"currentPage" | "prevPage"' instead, like this? If so, I can write up an answer. If not, can you explain why you prefer the string literal error message? Commented Jan 9, 2022 at 21:39
  • This is not specifically what I asked, your suggestion is even more readable, I think, so yes, I would accept your answer. EDIT: Although another answer does answer the question directly, I will have to accept that one, sorry. Commented Jan 13, 2022 at 7:49

1 Answer 1

1

This question might be helpful for you.

You can use conditional types, like here:

type KeysOfTypeNumber<T> = { [Key in keyof T]: T[Key] extends number ? Key : never }[keyof T]

type Keys = {
    currentPage: number
    prevPage: number
    searchParam: string
}

type CustomError = 'Argument must be of type number inside the generic'
const passNumberKeys = <Prop extends string>(
    numberTypeKeys: Prop extends KeysOfTypeNumber<Keys> ? Prop : CustomError
) => {
    console.log(numberTypeKeys)
}

passNumberKeys('currentPage') // OK

// Argument of type '"searchParam"' is not assignable to parameter of type '"Argument must be of type number inside the generic"'
passNumberKeys('searchParam') 

Playground

Please keep in mind that using explicit generic parameter Keys in this line passNumberKeys<Keys>('currentPage') which is not binded to argument is unsafe.

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.