我编写了一个更新函数,它接受一个对象T
和一个“更新程序”对象,该对象获取与T
相同的键(或子集)并提供更新功能原始对象的对应值。
type UpdaterObj<T> = {
[K in keyof Partial<T>]: (t: T[K]) => T[K]
};
declare function update<T>(obj: T, updaterObj: UpdaterObj<T>): T
示例用法如下:
const foo = {
x: 1,
y: "1"
};
update(foo, {
x: (xx: number) => xx + xx,
y: (yy: string) => yy + yy,
}); // Result is { x: 2, y: "11" }
这很有效,但我真的想删除这些注释,只写x: (xx) => xx + xx
和y: (yy) => yy + yy
,但Parameter implicitly has type 'any'
和xx
都会出现yy
错误x:
。
这很奇怪,因为如果我将鼠标移到xx
上,它会正确地推断相应的值应该是什么,并且如果我将yy
或def fun(line, filename):
file = open(filename, 'r')
output=''
empty=False
for i in file:
if(i.rstrip('\n')==line or empty):
empty=True
output+=i.rstrip('\n')
if(i.rstrip('\n')==''):
empty=False
return output
filename=input("Enter file name")
line=input("Input line")
output=fun(line,filename)
print(output)
注释为错误的类型,它会抱怨我我很确定我之前看过打字稿做出类似的推论。
在这种情况下,注释非常简单,但如果我深入到对象内部或者使用更复杂的类型,那么注释会很烦人,因此推理在这里会非常有用。
是否有任何简单的调整我的定义或我的用法可以让打字稿为我推断这个?
答案 0 :(得分:3)
我不确定GitHub中是否存在关于函数参数的类型推断如何与泛型类型参数的推断相互作用的问题,因此我不知道是否存在& #39;功能签名的简单调整,使其在不影响呼叫站点的情况下工作。
查看TypeScript spec,我看到TypeScript函数表达式(如xx => xx + xx
),
当没有类型参数且没有参数类型注释的函数表达式按类型
T
进行上下文类型化时,可以从S
中提取上下文签名T
,处理函数表达式,就好像它已明确指定S
中存在的参数类型注释一样。[snip]
从函数类型
S
中提取上下文签名T
,如下所示:
如果
T
是一个只有一个呼叫签名的函数类型,而如果该调用签名是非泛型,则S
就是该签名。如果
T
是联合类型... [snip]否则,无法从
T
中提取上下文签名。
因此,原始调用中的{xx => xx + xx
}具有(t: T['x']) => T['x']
形式的函数类型,其中包含类型参数T
,因此它看起来不像处理该函数就像它具有显式类型参数一样。据推测,这意味着编译器在消除泛型参数之前尝试提取上下文签名。
如果可以更改呼叫站点,那么我可以做出的最简单的建议是将两个参数update()
函数分解为curried函数,如下所示:
declare function updateCurried<T>(obj: T): (updaterObj: UpdaterObj<T>) => T
将使用如下(注意函数调用的顺序):
updateCurried(foo)({
x: xx => xx + xx,
y: yy => yy + yy,
}); // okay
这实质上迫使编译器在评估updaterObj
参数时,评估并消除泛型类型参数,此时它可以执行上下文功能参数推断,如上文摘录中所述。规格。
希望对您有所帮助。祝你好运!