【发布时间】:2015-01-18 15:33:17
【问题描述】:
我发现以下 getter 函数非常有用且可重用,因为它可以获取具有此类属性的 any 对象的属性 key 的值。
export function keyOf<a>(value: { key: a; }) : a {
return value.key;
}
同样我可以定义一个通用的setter函数:
export function withKey<a>(value: { key: a; }, key: a) : void {
value.key = key;
}
唯一的问题是,我需要它返回原始对象 value 和修改后的 key 属性,而不是返回 void。像这样的:
export function withKey<b, a extends { key: b }>(value: a, key: b) : a {
value.key = key;
return value;
}
但这不是一段有效的 TypeScript 代码。
问题:我怎样才能获得一个类型安全的通用 setter 函数,它返回原始对象及其属性集?
更新:
在当前 TypeScript 中,类型参数之间的依赖关系是被禁止的。我相信这样做是为了使类型系统更简单、更快。但是,此限制会阻止某些有用的场景,例如所讨论的场景。有一个 hack 可以将类型参数之间的依赖关系变成函数依赖关系:
export function withKey<a, b>(
value: a,
key: b,
toAssignable: (value: a) => { key: b } = function<c>(anything: c) : c {
return anything;
}
) : a {
toAssignable(value).key = key;
return value;
}
这看起来很丑陋并且改变了原始签名,但它可以编译和工作。
有人知道更好的方法吗?
【问题讨论】:
-
您的通用 setter 函数看起来像是从不同语言导入的反模式。请参阅Stack Overflow: get and set in TypeScript,但如果您坚持通用 setter 概念,请探索语言关键字
interface和implements,例如在Stack Overflow: Whats the difference between “declare class” and “interface” in TypeScript -
从什么时候泛型函数成为反模式? Classe 过于笨拙,需要将其实例化为对象,这会引入不必要的开销。
-
我不会争论它是否是一种反模式,但是:您将如何 使用您的方法,但不要为它创建一个对象来处理它?
-
首先它不是一个方法,它是一个函数。 Difference between a method and a function。像这样的功能有很多有用的场景。在我的特殊情况下,我需要它在 TypeScript 中实现 lenses。
标签: typescript