JSDOC:接受基类的实例,并在“@type”标签中接受它的子类

发布于 2025-02-08 15:31:05 字数 2808 浏览 1 评论 0原文

我有一个由子类扩展(valioratorRequired)的基类(验证器)。

然后,在另一个类中,我想拥有一个可能是基类类型的实例集合(验证器)或其任何后代(valifatorRequired)。

但是,当我尝试创建子类的实例并将其放置在该集合中(在formfield分配的表达式类型类型验证了验证wasteratorRequired是可分配到类型验证器:

”

我怀疑错误来自我没有定义@type 正确标记。

解决该检查的正确方法是什么?

formfield.js

import { ValidatorRequired } from './ValidatorRequired';

export class FormField {
    /**
     * Field's current value.
     *
     * @type {number|string}
     */
    value;

    /**
     * A collection of validators that should be run each time the field is validated.
     *
     * @type {Object.<string, Validator>}
     */
    validators = {};

    constructor({ required }) {
        this.required = Boolean(required);

        // The part after the `=` operator is underlined with grey as a weak warning
        this.validators.validatorRequired = new ValidatorRequired({ formField: this });
    }
}

valivator.js

export class Validator {
    /**
     * The field to validate.
     *
     * @type {FormField}
     */
    formField;

    /**
     * @param formField {FormField}
     */
    constructor({ formField }) {
        this.formField = formField;
    }

    /**
     * Validates a field.
     * Should be overridden by child classes.
     *
     * @returns {boolean}
     */
    validate() {
        return this.success();
    }

    /**
     * Ends validation with successful result.
     *
     * @returns {boolean}
     */
    success() {
        return true;
    }

    /**
     * Ends validation with an error.
     *
     * @returns {boolean}
     */
    error() {
        return false;
    }
}

validatorRequired.js

import { Validator } from './Validator';

/**
 * A validator that checks for field's value to be non-empty when it is required.
 */
export class ValidatorRequired extends Validator {
    /**
     * Validates a field.
     *
     * @returns {boolean}
     */
    validate() {
        // If the field is not required, return success.
        if (!this.formField.required) {
            return this.success();
        }

        // If the value is not falsy, return success.
        if (this.formField.value) {
            return this.success();
        }

        // If all previous checks have failed, return error.
        return this.error();
    }
}

I have a base class (Validator) that is extended by a child class (ValidatorRequired).

Then in another class I want to have a collection of instances that may be of base class type (Validator) or any of its descendants (ValidatorRequired).

However, when I try to create an instance of a child class and place it inside that collection (at FormField class constructor), I get a weak warning from PhpStorm: Assigned expression type ValidatorRequired is not assignable to type Validator:

PhpStorm inspection "Assigned expression type ValidatorRequired is not assignable to type Validator"

I suspect the error comes from the fact I've not defined the @type tag correctly.

What is the correct way to fix that inspection?

FormField.js:

import { ValidatorRequired } from './ValidatorRequired';

export class FormField {
    /**
     * Field's current value.
     *
     * @type {number|string}
     */
    value;

    /**
     * A collection of validators that should be run each time the field is validated.
     *
     * @type {Object.<string, Validator>}
     */
    validators = {};

    constructor({ required }) {
        this.required = Boolean(required);

        // The part after the `=` operator is underlined with grey as a weak warning
        this.validators.validatorRequired = new ValidatorRequired({ formField: this });
    }
}

Validator.js:

export class Validator {
    /**
     * The field to validate.
     *
     * @type {FormField}
     */
    formField;

    /**
     * @param formField {FormField}
     */
    constructor({ formField }) {
        this.formField = formField;
    }

    /**
     * Validates a field.
     * Should be overridden by child classes.
     *
     * @returns {boolean}
     */
    validate() {
        return this.success();
    }

    /**
     * Ends validation with successful result.
     *
     * @returns {boolean}
     */
    success() {
        return true;
    }

    /**
     * Ends validation with an error.
     *
     * @returns {boolean}
     */
    error() {
        return false;
    }
}

ValidatorRequired.js:

import { Validator } from './Validator';

/**
 * A validator that checks for field's value to be non-empty when it is required.
 */
export class ValidatorRequired extends Validator {
    /**
     * Validates a field.
     *
     * @returns {boolean}
     */
    validate() {
        // If the field is not required, return success.
        if (!this.formField.required) {
            return this.success();
        }

        // If the value is not falsy, return success.
        if (this.formField.value) {
            return this.success();
        }

        // If all previous checks have failed, return error.
        return this.error();
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

岁月如刀 2025-02-15 15:31:05

事实证明,该错误不在JSDOC中的@Type标签中,而不是PhpStorm如何处理该类别指定的类。

我的反应库在项目中的其他地方导入。 React具有定义的类验证器。 phpStorm意识到这一点,并认为我在JSDOC中指定的验证器是React中的验证器,而不是我自己的验证器

当您尝试通过JSDOC注释 validators field( ctrl + +单击课程,或单击课程,或将光标放在班级,然后按 ctrl + b )。如果这样做,您将获得一个“选择声明”对话窗口,其中所有可能的声明都列出:

< img src =“ https://i.sstatic.net/2gciz.png” alt =“选择声明&quort”对话窗口窗口>

因此,解决方案是使phpStorm想到valy> valiver> valiverator指定的是我自己的班级100%。 很容易地完成此操作。

通过明确导入验证器formfield.js

import { Validator } from './Validator';

此解决方案的较小的下降:您的base类(validator),可以 包含在捆绑包中,无论是否使用。但是,我认为这会产生可忽略的影响,因为:

  1. 如果您使用的是基类的后代,那么您当然会在捆绑包中包含基类(类validatorRequired扩展了<代码>验证器)。
  2. 如果您不使用任何记录@Type tag(class formfield)的后代,则可能是在类的后代中使用它们记录用法(FormField后代),或者您做错了什么。
  3. 基类的大小可能太小了,无法对捆绑包产生巨大影响。

Turns out the error was not in the @type tag in JSDoc, rather in how PhpStorm treats the class that is specified there.

I have React library imported somewhere else in my project. And React has a class Validator defined. PhpStorm is aware of that and thinks the Validator I specified in JSDoc is the Validator in React and not my own Validator.

This fact is proved when you try going to the definition of class Validator through JSDoc comment for validators field (Ctrl + click on the class, or place a cursor at the class and press Ctrl+B). If you do that, you get a "Choose Declaration" dialogue window, where all the possible declarations are listed:

"Choose Declaration" dialogue window

So the solution is to make PhpStorm think the Validator specified is 100% my own class. This is easily done by explicitly importing the Validator:

FormField.js:

import { Validator } from './Validator';

This solution has a minor downside: your base class (Validator) will be included in the bundle regardless of whether it is used or not. However, I think this has a negligible impact, because:

  1. If you use a class that is a descendant from the base class, you certainly will have the base class included in the bundle anyway (class ValidatorRequired extends Validator).
  2. If you don't use any of the descendants right where you document the @type tag (class FormField), you are probably using them in the descendants of the class that is documenting the usage (FormField descendants), or you are doing something wrong.
  3. The size of the base class is probably too tiny to bring a vast effect on the bundle.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文