jsDoc 定义隐式分配的构造函数属性(不使用 `this` 设置)

问题描述 投票:0回答:1

在 VS Code 中使用 jsDoc,我们如何定义构造函数的属性,其属性不是直接通过

this.property = value
语法设置,而是通过
Object.assign()
代码隐式设置,如以下示例所示:

/** 
 * @constructor
 * @property {string} title - the @property here has no effect to define such properties to IDE 
 */
function BookFn(title, description, year, author, lang, genre, pages, isbn, copies) {
  
  //instead of writing multiple this.x = y code,
  //we set our properties indirectly via 'Object.assign()' as follow:
  Object.assign(this, {title, description, year, author, lang, genre, pages, isbn, copies}); 
  
}

BookFn.prototype = {
  titleAuthor() { return this.title + ' by ' + this.author}, //VSCode IDE doesn't know such properties!
};

let book1 = new BookFn('book1', 'description1', 2020, 'author1', 'English', 'genre1', 600, 'isbn1', 5000);
let t = book1.title; //VSCode IDE doesn't know such property!

我尝试过

@property
来显式定义我们的属性,但没有任何效果。

javascript function visual-studio-code this jsdoc
1个回答
0
投票

这有点棘手...

如果您希望 IntelliSense 通过

Object.assign()
识别赋值,那么您必须使用返回值。

这是一个例子:

class classA
{
   static prop1 = 1;
}

class classB
{
   static prop2 = 2;
}

const classC = Object.assign(classA, classB);

// IntelliSense will recognize this:
console.log(classC.prop1);
// Outputs: 1

// IntelliSense will recognize this:
console.log(classC.prop2);
// Outputs: 2

// JavaScript works fine, but IntelliSense will not recognize this:
console.log(classA.prop2);
// ----------------^
// IntelliSense will show an error here.
// But JavaScript will output: 2

还有一个问题...

function theConstructor ()
{
   // ...
}

上面的函数可以调用为

theConstructor()
new theConstructor()

如果不使用

new
关键字,则 IntelliSense/JSDoc 将推断函数返回类型。但如果使用
new
关键字,那么结果将始终是
InstanceType < typeof theConstructor >

因此,如果您的函数如下所示,那么它应该适用于大多数情况:

/**
 * @template [ Initializer = {} ]
 * @param { Initializer } [ initializer = Initializer ]
 */
function theConstructor ( initializer )
{
   const target =
   (
      /**
       * No need to cast here.
       */
      ( ( typeof new.target != 'undefined' ) ? new.target : theConstructor )
   );
   
   const instance =
   (
      /**
       * No need to cast here.
       */
      ( ( this instanceof target ) ? this : new target )
   );
   
   const prototype =
   (
      /**
       * Cast the prototype as an instance of this class.
       * 
       * @type { InstanceType < typeof theConstructor < Initializer > > }
       */
      ( target.prototype )
   );
   
   // Make sure that `initializer` is an object to avoid JS error.
   initializer = Object(initializer);
   
   return Object.assign(instance, prototype, initializer);
}

// Set your default properties...
theConstructor.prototype.title = 'Untitled';

// TESTING:
const initializer = { nonDefault: 'value' };
const result = theConstructor(initializer);
const instance = new theConstructor(initializer);

// IntelliSense will recognize the following:
{
   result.title;
   result.nonDefault;
   
   instance.title;
}

// IntelliSense will NOT recognize the following:
{
   instance.nonDefault;
   // ------^
   // IntelliSense will show an error here.
}

我希望这可以帮助您使您的文档更好地适用于 VSCode。

© www.soinside.com 2019 - 2024. All rights reserved.