Sorry for the vague title, but I don't know how to express this problem concisely.
Basically, I have the following code (with unimportant bits removed):
function identity<T>(value: T): T {
return value;
}
function extent<T, K>(
values: T[],
map: (value: T) => K = identity // the '= identity' part gives an error
): [K, K] | undefined {
let min;
let max;
// ... stuff ...
return min === undefined || max === undefined ? undefined : [map(min), map(max)];
}
Where the default = identity
value results in a compiler error.
I can remove the default value for the map
parameter from the extent
's signature and always provide one myself:
extent([5, 1, 3, 4, 8], x => x)
Which will work just fine, but I'd rather not supply the second parameter, unless I'm actually mapping the values from one type to another.
How do I type the indentity
function so that it's accepted as the default value for extent
's map
parameter? I'm stuck on TypeScript 3.6 for the time being, if that matteres.
CodePudding user response:
Probably the best way to deal with this that maintains type-safety to the outside world is via overloads:
function extent<T>(values: T[]): [T, T] | undefined
function extent<T, K>(values: T[], map: (value: T) => K): [K, K] | undefined
function extent<T, K>(
values: T[],
map?: (value: T) => K
): [K, K] | [T, T] | undefined {
const actualMap = map ?? identity;
let min;
let max;
// ... stuff ...
return min === undefined ||
max === undefined ?
undefined :
[actualMap(min), actualMap(max)];
}
CodePudding user response:
It's because of type error.
In map
parameter you declare that this function will return the type of K
but in the identity
function you expect that to return the type of T
so you can't assign it as a default value.
You could fix it like this: map: (value: K) => K = identity
CodePudding user response:
There is a conflict with T => K
type of map and K => K
type in identity function. Making identity
less strict on types can help:
function identity<T>(value: T): any {
return value;
}
or even
const identity = (x: any) => x;