搜索词
设置器不能返回值
装饰器
建议
默认情况下,JavaScript不对设置器的返回值做任何处理,但这并不是错误。
允许设置器作为默认行为并添加标志以打开错误。
使用场景
- 覆盖设置器并使用原始设置器返回值的装饰器。
- 直接调用设置器函数并期望返回值的方法。
示例
一个实时示例是来自ember-decorators的@computed
,它与ember的旧行为相匹配。
使用遗留装饰器的代码示例(也可以使用阶段2装饰器):
function saved (target: {}, key: string | symbol, descriptor: PropertyDescriptor) {
const savedStore = new WeakMap();
const oldSet = descriptor.set;
if (!oldSet) {
throw new Error('Must be used on setter only');
}
const oldGet = descriptor.get;
return {
...descriptor,
get () {
let response = savedStore.get(this);
if (!response && oldGet) {
response = oldGet.call(this);
}
return response;
},
set (value: any) {
const result = oldSet.call(this, value);
savedStore.set(this, result);
}
};
}
class Foo {
@saved
get square () {
// default value of 1 if none is saved
return 1;
}
set square (value: number) {
return value * value;
}
}
检查清单
我的建议满足以下指导原则:
- 这不会对现有的TypeScript / JavaScript代码造成破坏性更改
- 这不会改变现有JavaScript代码的运行时行为
- 这可以在不根据表达式的类型发出不同的JS的情况下实现
- 这不是一个运行时特性(例如新的表达式级语法)
4条答案
按热度按时间cclgggtu1#
在对这个问题进行进一步思考后,我认为可能有一个更好的解决方案。
与其仅仅允许set返回,如果有任何装饰器,那么setter和getter的预期类型可以由装饰器确定,并且在没有访问器装饰器存在时应该具有当前行为的默认值。
如果这是一个更可取的建议,我可以相应地更新标题和描述,或者是否应该创建一个新的问题并将其关闭?
由于装饰器尚未达到第三阶段,是否已经设置了一个跟踪机制(标签?)来区分在新实现开始工作时的提议?
hof1towb2#
我希望看到允许属性装饰器返回
PropertyDescriptor<T>
,并反过来被装饰的属性将是类型为T
的。目前我的装饰器代码返回一个属性描述符,但我不得不表达属性的类型。
例如:
如果
mydecorator
返回PropertyDescriptor<string>
,我希望 TSC 能够推断出myprop
的类型为string
u1ehiz5o3#
我将为这个投一票。在用作“setter”的函数中的一个
return
语句在规范中不是错误,并且在大多数浏览器中只是默默地被忽略。另一个用例:
我制作了一个“AutoImplemented”装饰器,它将为属性创建一个带有
_
前缀的后备字段,添加getter函数,并自动替换对它的赋值。只接受脏值。它还将在原型中生成
$getName
和$setName
助手,以允许覆盖访问器,这仍然是针对ES5
的问题。( 338 , 4465 )updateWhenValueIsDirty
应该仅在值实际更改时调用,但super.name = value
语句无法告诉我赋值是否执行(甚至在ES5中也无法编译)。将setter方法作为示例方法调用并检查其返回值是使此工作的方法。xzlaal3s4#
嗯,我们需要一个标志来阻止或绕过这种错误!
在一个良好的设计模式中,我们可能希望使用返回来打破条件流程。
举个例子:
而不是
很多人不喜欢
elseif design
,所以使用batch if return
也是有效的中断方式!谢谢
为了在概念上更抽象,这是一个很好的setter设计: