l-liava-l,
сенк попробую |
Как описать в jsdoc параметрический полиморфизм конструктора? А именно, то что он может вызываться следующим образом:
new Point( {x: {Number}, y: {Number}}.<Point> ); // передается другой экземпляр {Point} new Point( [x {Number}, y {Number}].<Array> ); // массив с координатами new Point( x {Number}, y {Number} ); // координаты ? |
nerv_,
/** * * @param {(number|Point|number[])} paramOrX * @param {number} [y] * @constructor */ function Point(paramOrX, y) { } Хотя, как по мне, правильнее будет выбрать что-то одно -- я бы предпочел два параметра, x и y, тогда проблему с массивами решаем через new Point(...[x, y]), а для других Point'ов заведи статик метод типа Point.fromPoint(point) или метод clone в прототипе. |
nerv_, @variation
|
Цитата:
'use strict'; export default class Point { /** * @param {Point|Array<Number>} some */ constructor(...some) { let [x, y] = Point.factory(some); this.x = x; this.y = y; } /** * @returns {Point} */ clone() { return new Point(this); } /** * @param {Array} some * @returns {Object} */ static factory(some) { if (some instanceof Array) { switch (some.length) { case 2: return some; case 0: return [0, 0]; default: break; } } if (some instanceof Point) { return [some.x, some.y]; } if (some instanceof Object) { if ('x' in some && 'y' in some) { return [some.x, some.y]; } } throw new TypeError(`This type not supported.`); } } --- FINoM, пример? Шторм вроде как не подхватывает... |
/** * @interface */ class Base { constructor() { Object.assign(this, this.constructor.castConstructorData(...arguments)); } clone() { return new this.constructor(this); } static castConstructorData() {}; } class Point extends Base { /** * * @param {(number|Point|{x: number, y: number})} pointOrX * @param {number} [y] */ constructor(pointOrX, y) { super(...arguments); } /** * @see Point */ static castConstructorData(pointOrX, y) { if (typeof pointOrX === 'number') { return {x: pointOrX, y}; } if (typeof pointOrX === 'object') { return {x: pointOrX.x, y: pointOrX.y}; } throw new TypeError(`Invalid arguments for Point`); } } console.log(new Point(1, 2)); console.log(new Point({x: 1, y: 2})); console.log(new Point(new Point(1, 2))); console.log(new Point(1, 2).clone()); |
Цитата:
|
nerv_, с @variation нужно несколько раз объявить метод или класс:
/** * method x * variation 1 * ... */ /** * method x * variation 2 * ... */ Цитата:
|
trikadin, сравни это
class Point { /** * @param {Point|Array<Number>} some */ constructor(...any) { let [x, y] = Point.factory(any); this.x = x; this.y = y; } } и это /** * @interface */ class Base { constructor() { Object.assign(this, this.constructor.castConstructorData(...arguments)); } } в первом случае я сразу вижу свойства объекта, во втором - кто его знает что там :) FINoM, можно больше кода? Напиши для функции foo() пример. --- забыл, что можно запускать уже подобный код в браузере :) 'use strict'; class Point { /** * Examples: * new Point() * new Point(1, 2) * new Point([3, 4]) * new Point({x: 5, y: 6}) * new Point(new Point(7, 8)) * * @param {Point|Array<Number>} some */ constructor(some) { let xy = Point.factory(Array.from(arguments)); // все-таки нельзя пока без доводки руками =( this.x = xy[0]; this.y = xy[1]; } /** * @returns {Point} */ clone() { return new Point(this); } /** * @param {Point|Array<Number>} some * @returns {Object} */ static factory(some) { if (!some.length) { return [0, 0]; } if (some.length === 2) { return some; } let first = some[0]; // some.length === 1 if (first instanceof Array) { return first; } if (first instanceof Point) { return [first.x, first.y]; } if (first instanceof Object) { if ('x' in first && 'y' in first) { return [first.x, first.y]; } } throw new TypeError(`This type not supported.`); } } console.log(new Point()); console.log(new Point(1, 2)); console.log(new Point([3, 4])); console.log(new Point({x: 5, y: 6})); console.log(new Point(new Point(7, 8))); |
nerv_, ты сравнил интерфейс и имплементацию О_о
Используй class properties из es7, и будет сразу отлично видно, какие свойства у класса есть. Советую в связке с flow -- webstorm его хорошо держит, это удобнее, чем jsdoc. |
Часовой пояс GMT +3, время: 04:43. |