@halospv3/hce.shared-config
Version:
Automate commit message quality, changelogs, and CI/CD releases. Its `main` entry point is a Semantic Release config. Functions and classes are exposed for customization. An ESLint config, a Commitlint config, and addl. resources for .NET projects are als
1 lines • 3.26 kB
Source Map (JSON)
{"version":3,"file":"isConstructor.mjs","names":[],"sources":["../../../src/utils/reflection/isConstructor.ts"],"sourcesContent":["/**\n * A very jank function to determine if an object can be the target of Reflect.construct.\n * Unfortunately, many functions have a constructor in their prototype. These\n * functions are treated like classes due to JavaScript's poor distinction between\n * classes and functions.\\\n * Typescript can enforce \"new\" keyword usage, but overriding the type\n * allows you to `new isConstructor()` despite this function not intended to be\n * used with the `new` keyword.\n * #### NOTE: Only works when targeting ES6/ES2015 or later.\n * > If your project or a dependent project is compiled to < ES6, this function will always return `false`; classes and constructors were introduced in ES6/ES2015.\n * @param object Anything.\n * @returns `true` if the {@link object} is a constructor. Else, `false`.\n * @since 3.0.0\n * @see https://stackoverflow.com/a/49510834\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function isConstructor(object: unknown): object is abstract new (...arguments_: any[]) => any {\n // Method 0 - filter\n if (typeof object !== 'function')\n return false;\n\n // Method 1\n // statically-defined class\n if (/^class\\s/.test(object.toString()))\n return true;\n\n /* Method 2\n * > class class_ {}; function func(){}\n * undefined\n * > class_.prototype.constructor.name === class_.name\n * true\n * > func.prototype?.constructor?.name === func.name\n * false\n * typeof String.prototype ==='object'\n * > true\n * typeof Function.prototype === 'object';\n * > false\n * typeof Function.prototype\n * > 'function'\n */\n const prototype: unknown = object.prototype;\n if (prototype != undefined\n && (typeof prototype === 'function' || typeof prototype === 'object')\n && 'constructor' in prototype\n && typeof prototype.constructor === 'function') {\n const _ctor = prototype.constructor as (new (...arguments_: unknown[]) => unknown);\n const _name = Reflect.getOwnPropertyDescriptor(\n _ctor,\n 'name',\n );\n // short-circuit if `obj.prototype.constructor` is a function, but not a constructor. Return false.\n return (\n _ctor === object\n && _name?.writable === false\n && _name.enumerable === false\n && _name.configurable === true\n );\n }\n\n // Short-circuit\n // Method 3 catches exceptions when !isConstructor. When debugging, that's annoying.\n return false;\n\n // Method 3\n // isConstructable (See https://stackoverflow.com/a/49510834)\n // try {\n // // @ts-expect-error ts(2351): Type 'Function' has no construct signatures.\n // new new Proxy(obj, { construct: () => ({}) })()\n // return true\n // }\n // catch {\n // return false\n // }\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAgBA,SAAgB,cAAc,QAAuE;CAEnG,IAAI,OAAO,WAAW,YACpB,OAAO;CAIT,IAAI,WAAW,KAAK,OAAO,SAAS,CAAC,GACnC,OAAO;CAgBT,MAAM,YAAqB,OAAO;CAClC,IAAI,aAAa,KAAA,MACX,OAAO,cAAc,cAAc,OAAO,cAAc,aACzD,iBAAiB,aACjB,OAAO,UAAU,gBAAgB,YAAY;EAChD,MAAM,QAAQ,UAAU;EACxB,MAAM,QAAQ,QAAQ,yBACpB,OACA,MACF;EAEA,OACE,UAAU,UACP,OAAO,aAAa,SACpB,MAAM,eAAe,SACrB,MAAM,iBAAiB;CAE9B;CAIA,OAAO;AAYT"}