简体   繁体   English

如何在 JavaScript/VSCode/TypeScript 中声明 setter 的类型?

[英]How to declare the type of a setter in JavaScript/VSCode/TypeScript?

I have a very simple example, to demonstrate the issue:我有一个非常简单的例子来演示这个问题:

class Person {
    _name = '';
    _age  = 0;
    get name() {
        return this._name;
    }
    /**
     * @type {string}
     */
    set name(name) {
        this._name = name;
    }
    get age() {
        return this._age;
    }
    /**
     * @type {number | string}
     */
    set age(age) {
        if (age === 'too old') {
            age = 100000;
        }
        this._age = age;
    }
}

I use VSCode to do typechecking, but why does it fail on the type?我使用 VSCode 进行类型检查,但为什么它会在类型上失败?

I explicitly say that the age setter can take either a number or a string:我明确地说年龄设置器可以采用数字或字符串:

在此处输入图像描述

You didn't define the type but instead wrote a JSDoc comment.您没有定义类型,而是写了一个 JSDoc 注释。 That doesn't actually affect your code.这实际上不会影响您的代码。 Thus TypeScript implicitly sets the type number .因此 TypeScript 隐式设置类型number

If you want the setter to accept both string and number one solution would be to use a union type like this:如果您希望 setter 同时接受stringnumber一个解决方案,则可以使用这样的联合类型:

set age(age: string | number) {
   ...
}

Keep in mind that you get problems when setting this._age later on because this._age also implicitly has the type number (default value 0 ) and therefore cannot be assigned a value of type string | number请记住,稍后设置this._age时会出现问题,因为this._age也隐式具有类型number (默认值0 ),因此不能分配类型为string | number的值。 string | number . string | number

I believe you need to wrap your union types in parenthesise to be valid in JSDoc:我相信您需要将联合类型用括号括起来才能在 JSDoc 中有效:

/**
* @type {(number | string)}
*/

From the documentation :文档中:

Multiple types (type union) This can be a number or a boolean.{(number|boolean)} This means a value can have one of several types, with the entire list of types enclosed in parentheses and separated by |.多种类型(联合类型) 这可以是数字或 boolean。{(number|boolean)} 这意味着一个值可以具有多种类型之一,整个类型列表用括号括起来并用 | 分隔。

The following snippet should work.以下代码段应该可以工作。 Just check the type of age with typeof to narrow the type into an if statement.只需使用typeof检查age的类型,即可将类型缩小为if语句。

class Person {
  _name = '';
  _age  = 0;
  get name() {
      return this._name;
  }
  /**
   * @param {string} name
   */
  set name(name) {
      this._name = name;
  }
  get age() {
      return this._age;
  }
  /**
   * @param {number | string} age
   */
  set age(age) {
      if (typeof age === 'string') {
        if (age === 'too old') {
          age = 100000;
        } else {
          age = parseInt(age)
        }
      }
      this._age = age;
  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM