仕様: https://github.com/wycats/javascript-decorators
プロパティ自体に decorator は付か無いので、しかたなく setter を作ったけど、なんかうまくできないだろうか。
(この使い方自体が筋悪な気もするが、 decorator でやりたいのってこういうのな気がする。)
// $ babel-node --optional es7.decorators index.js
class Assert {
private(target, name, descriptor) {
let value;
descriptor.set = (val) => {
value = val;
}
descriptor.get = () => {
return value;
}
}
required(target, name, descriptor) {
let original = descriptor.set;
descriptor.set = (val) => {
console.assert(val !== undefined, `${name} is required`);
original(val);
}
}
validate(target, name, descriptor) {
let original = descriptor.set;
descriptor.set = (val) => {
console.assert(val.method !== undefined, `${name}.val is required`);
let method_list = ['get', 'post', 'put', 'delete'];
console.assert(method_list.indexOf(val.method) > -1, `${name}.val should be one of ${method_list} but ${val.method}`);
original(val);
}
}
}
var assert = new Assert();
class Fetcher {
@assert.required
@assert.private
set url(val) {}
@assert.validate
@assert.required
@assert.private
set option(val) {}
constructor(url, option) {
this.url = url;
this.option = option;
}
}
var fetcher = new Fetcher('http://example.com', { method: 'get' });
console.log(fetcher); // {}
console.log(fetcher.url); // http://example.com
console.log(fetcher.options); // { method: 'get' }
追記
関数の引数を先に奪ってバリデート
class Fetcher {
@assert.required
@assert.private
set url(val) {}
@assert.validate
@assert.required
@assert.private
set option(val) {}
constructor(url, option) {
this.url = url;
this.option = option;
}
}
var fetcher = new Fetcher('http://example.com', { method: 'get' });
console.log(fetcher); // {}
console.log(fetcher.url); // http://example.com
console.log(fetcher.options); // { method: 'get' }
汎用の関数 wrapper を作るアノテーションを別途用意。
class Fetcher {
@assert.required
@assert.private
set url(val) {}
@assert.validate
@assert.required
@assert.private
set option(val) {}
constructor(url, option) {
this.url = url;
this.option = option;
}
}
var fetcher = new Fetcher('http://example.com', { method: 'get' });
console.log(fetcher); // {}
console.log(fetcher.url); // http://example.com
console.log(fetcher.options); // { method: 'get' }