具有无点函数的通用类型
Generic types with point-free functions
假设我有下一个功能:
function cast<T>(v: any): T {
return v as T;
}
现在,我有一个数组,我想使用 map 投射:
const arr = [1, 3, 5];
// works
arr.map(value => cast<number>(value));
// but I want
arr.map(cast<number>);
可能吗?我可以在无点地图上传递通用吗?
你想要的是不可能的,因为 cast<number>
不被视为数组映射所需的回调函数。
您可以通过简单地在控制台中记录它们来尝试查看什么是函数,什么不是函数。
尝试console.log(cast)
并且 console.log(cast<number>)
实际上,数组原型中的方法map
是通用的。
Array<T>.map<U>(callback: (value: T, index: number, array: T[]) => U): U[]
因此,通过将您的 cast
函数与任何类型参数一起使用(例如将其用作无指针)returns unknown
。完全符合预期。
你可以像这样投射你的数组
const arr = [1, 3, 5];
const re = arr.map<string>(cast);
Here 关于这个很有趣 post。
我 post 几个月后读到这篇文章时,另一个想法突然闪过我的脑海。
另一个解决方案可能是一个函数包装器,用于将类型参数显式传递给 cast
函数。
type Fn<T> = (element: any) => T;
const cast = <T>(element: any): T => {
return element as T;
}
const caster = <T>() => {
return cast as Fn<T>;
}
const dut: any[] = [1, 2, 3, 4, 5, 6];
const casted = dut.map(caster<number>());
// casted is of type number[]
虽然主要解决方案仍然是最好的,但这种方法可以解决一些目标 API 不提供任何重载来推断类型的情况。
希望对您有所帮助。
使用无点样式的更多类型安全替代方案(Fail-Fast 运行-时间检查):
function assert(expr: unknown, msg = ""): asserts expr { if (!expr) throw Error(msg); }
const every = <T>(cb: (t: unknown) => t is T) => (a: unknown[]): a is T[] => arr.every(cb);
const isNumber = (mn: unknown): mn is number => typeof mn === "number"
const arr: unknown[] = ... // given some unknown array
assert(every(isNumber)(arr));
arr // arr now of type number[] (or has thrown, which could be fetched by an error handler)
假设我有下一个功能:
function cast<T>(v: any): T {
return v as T;
}
现在,我有一个数组,我想使用 map 投射:
const arr = [1, 3, 5];
// works
arr.map(value => cast<number>(value));
// but I want
arr.map(cast<number>);
可能吗?我可以在无点地图上传递通用吗?
你想要的是不可能的,因为 cast<number>
不被视为数组映射所需的回调函数。
您可以通过简单地在控制台中记录它们来尝试查看什么是函数,什么不是函数。
尝试console.log(cast)
并且 console.log(cast<number>)
实际上,数组原型中的方法map
是通用的。
Array<T>.map<U>(callback: (value: T, index: number, array: T[]) => U): U[]
因此,通过将您的 cast
函数与任何类型参数一起使用(例如将其用作无指针)returns unknown
。完全符合预期。
你可以像这样投射你的数组
const arr = [1, 3, 5];
const re = arr.map<string>(cast);
Here 关于这个很有趣 post。
我 post 几个月后读到这篇文章时,另一个想法突然闪过我的脑海。
另一个解决方案可能是一个函数包装器,用于将类型参数显式传递给 cast
函数。
type Fn<T> = (element: any) => T;
const cast = <T>(element: any): T => {
return element as T;
}
const caster = <T>() => {
return cast as Fn<T>;
}
const dut: any[] = [1, 2, 3, 4, 5, 6];
const casted = dut.map(caster<number>());
// casted is of type number[]
虽然主要解决方案仍然是最好的,但这种方法可以解决一些目标 API 不提供任何重载来推断类型的情况。
希望对您有所帮助。
使用无点样式的更多类型安全替代方案(Fail-Fast 运行-时间检查):
function assert(expr: unknown, msg = ""): asserts expr { if (!expr) throw Error(msg); }
const every = <T>(cb: (t: unknown) => t is T) => (a: unknown[]): a is T[] => arr.every(cb);
const isNumber = (mn: unknown): mn is number => typeof mn === "number"
const arr: unknown[] = ... // given some unknown array
assert(every(isNumber)(arr));
arr // arr now of type number[] (or has thrown, which could be fetched by an error handler)