'extends number but do not restrict to a specific number
Probably been asked and answered but I didn't find the answer - so I ask.
The workaround is not great as if I want to include more type it will not be as easy to upgrade. Any better way of doing it ?
declare const max: <A extends number | string> (a: A) => (b: A) => A
max (2) (3) // Argument of type '3' is not assignable to parameter of type '2'
max ('a') ('b') // Argument of type '"b"' is not assignable to parameter of type '"a"'
// Possible workaround but will become clumsy if possible type to extends grow
declare const maxClumsy: {
(a: number): (b: number) => number
(a: string): (b: string) => string
}
maxClumsy (2) (3)
maxClumsy ('a') ('b')
Solution 1:[1]
Following up on the comment from @matt-diamond
Keep in mind that you're passing in literals here... if the input variables are typed more broadly, you won't have an issue.
If you don't want to have to pass explicitly typed variables each time, you can use this method.
type Num = number | string
type AsNum<T> = T extends string ? string :
T extends number ? number : never
declare const max: <T extends Num>(a: T) => (b: AsNum<T>) => AsNum<T>
max(2,4) max('2','4') // OK
max(2,'4') // Argument of type 'string' is not assignable to parameter of type 'number'
max(true,false) // Argument of type 'boolean' is not assignable to parameter of type 'string | number'
Although it does look just as "clumsy" as your working suggestion, if not more.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |
