我想调整一些具有不同签名的现有功能,同时保持原件的类型/签名检查。
例如:
AVCaptureSessionPresetHigh
如您所见,我有许多函数可以返回各种不同的对象。我有一个函数addIndexToReturn,它适应这些,返回一个新的函数,为它们的返回值添加一个索引。
但是,新函数没有对其参数进行任何类型检查。
有什么想法吗?
答案 0 :(得分:1)
基本上你丢弃了参数函数的类型信息,因为你的返回lambda接收any[]
您可以尝试使用以下内容解决问题:
type Indexed<T> = T & { index: number };
function addIndexToReturn<T, V>(func: (param: T) => V, index: number) : (param:T) => Indexed<V> {
return (x:T) => {
let result = func(x) as Indexed<V>;
result.index = index;
return result;
}
}
但这仅适用于单参数功能。我不相信您可以正确表达具有任意值的函数,原因类似于my other recent answer。
如果我们要处理可变长度参数的情况,我们必须 将参数视为集合。因为所有变量都必须 有一个(虽然可能参数化)类型,所以也必须这样 集合对象。但是,各种功能的类型没有 对齐。
(param:A) => B
与(param:B) => C
和IF(RIGHT(@input, 2) = 'es') SELECT LEFT(@input, LEN(@input) - CHARINDEX('es', REVERSE(@input))) ELSE IF (RIGHT(@input, 1) = 's') SELECT LEFT(@input, LEN(@input) - CHARINDEX('s', REVERSE(@input)))
的类型不同 不能存储在同一个良好类型的容器中(限制联合类型 但那些也不会扩展。)
答案 1 :(得分:1)
这似乎可以使用来自LINQ的技巧 -
interface Adapter {
<A, T>(adaptee: (a: A) => T): (a: A) => T;
<A, B, T>(adaptee: (a: A, b: B) => T): (a: A, b: B) => T;
}
const fn = (x: String): String => x + y.toString();
const fn2 = (x: String, y: Number): String => x + y.toString();
const adapt: Adapter = (adaptee) => adaptee;
adapt(fn)(1)
adapt(fn)("")
adapt(fn2)(1, 2)
adapt(fn2)("", 2)