如何通过JSDoc正确推断对象的构造函数?

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

我想让这个函数接收参数并返回其类(如果

object
),参数本身(如果
function
)或遗留对象构造函数(如果有其他情况)。

在 JavaScript 中,下面的示例涵盖了大多数情况下的功能。但 JSDoc 不遵循...

export const ParseType = ( Subject ) =>
{
   if ( ( typeof Subject == 'function' ) && ( typeof Subject.prototype == 'object' ) )
   {
      return Subject;
   }
   
   return Object(Subject).constructor;
}

function MyCustomType ()
{
   
}
// JSDoc signature: () => void

const MyCustomInstance = new MyCustomType;
// JSDoc signature: any
// Expecting JSDoc signature: MyCustomType

const MyRetrievedCustomType = ParseType(MyCustomInstance);
// JSDoc signature: any
// Expecting JSDoc signature: typeof MyCustomType

要解决这个问题,我可以这样做:


/**
 * @template [Type = InstanceType < typeof Object >]
 * @param { Type } [Subject = Type]
 */
export const ParseType = ( Subject ) =>
{
   let Inferred;
   
   if ( ( typeof Subject == 'function' ) && ( typeof Subject.prototype == 'object' ) )
   {
      Inferred =
      (
         /**
          * @type { Type extends Function & { prototype: {} } ? Type : never }
          */
         ( Subject )
      );
   }
   
   else
   {
      const Instance =
      (
         /**
          * @type { Subject & {} }
          */
         ( Object(Subject) )
      );
      
      Inferred =
      (
         /**
          * @type { Type extends Function & { prototype: {} }
          *          ? never
          *          : Instance extends { constructor: infer Constructor }
          *             ? Constructor
          *             : never
          *       }
          */
         ( Instance.constructor )
      );
   }
   
   return Inferred;
}

/**
 * @constructor
 */
function MyCustomType ()
{
   
}
// JSDoc signature: typeof MyCustomType

const MyCustomInstance = new MyCustomType;
// JSDoc signature: MyCustomType

const MyRetrievedCustomType = ParseType(MyCustomInstance);
// JSDoc signature: Function
// Expected JSDoc signature: typeof MyCustomType
// JavaScript actual value: [Function MyCustomType]

const MyRegrievedStringType = ParseType('MyString');
// JSDoc signature: Function
// Expected JSDoc signature: StringConstructor
// JavaScript actual value: [Function String]

我无法正确从

Instance
中提取构造函数,因为 JSDoc 推断出
ObjectConstructor.constructor
处的构造函数,即
Function
。奇怪的是,当我从
constructor
中提取
Instance
时,在铸造 JSDoc 类型标记中,我可以针对任何类测试
Instance
并评估为“硬编码”类...

/**
 * @type { Instance extends MyCustomType ? typeof MyCustomType : never }
 */

甚至像这样链接...

/**
 * @type { Instance extends String ? typeof String : Instance extends BigInt ? typeof BigInt : never : never }
 */

但是我不能只是不断增加这个链并对可能在任何将使用此功能的项目中使用的所有类进行硬编码......

javascript constructor type-inference jsdoc jsdoc3
1个回答
0
投票

你做了很多奇怪的事情,但是如果我正确理解你问题的第一段,问题就简单多了。考虑这个片段:

const Classify = object => {
  if (object == null) // covers both null and underfined
    return object;
  return object.constructor;
}

console.log(Classify([]));
console.log(result = Classify(undefined));
console.log(result = Classify(null));

请注意,比较

object == null
涵盖了
null
undefined
对象。要区分
null
undefined
,您需要使用
===
比较运算符,但您不需要它来实现您的目的,因为在这两种情况下您都可以简单地返回
object

最后,还有另一种情况,也是最令人不愉快的一种:一些从未在代码中定义的想要成为变量(或常量)的情况。这只是一个毫无意义的名字。 重要提示:即使它转换为字符串为

"undefined"
,它与
undefined
无关。使用
typeof
可以检测到这种情况,但这几乎没有意义。这样的名字绝对是邪恶的,应该100%消除。因此,最好不要检查任何东西,而是放手看看调试器下的异常。如果您检查这种情况并解决它,您将得到充满垃圾的代码。

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