{"id":19589192,"url":"https://github.com/fasttime/polytype","last_synced_at":"2025-04-05T09:06:47.287Z","repository":{"id":45741097,"uuid":"57988696","full_name":"fasttime/Polytype","owner":"fasttime","description":"Dynamic multiple inheritance for JavaScript and TypeScript. Without mixins.","archived":false,"fork":false,"pushed_at":"2025-01-25T12:07:32.000Z","size":520,"stargazers_count":61,"open_issues_count":1,"forks_count":3,"subscribers_count":7,"default_branch":"main","last_synced_at":"2025-03-29T08:06:18.255Z","etag":null,"topics":["class","classes","es2020","inheritance","multiple-inheritance"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fasttime.png","metadata":{"files":{"readme":"readme.md","changelog":"changelog.md","contributing":null,"funding":null,"license":"license.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-05-03T17:40:28.000Z","updated_at":"2025-03-07T06:18:25.000Z","dependencies_parsed_at":"2023-11-21T07:52:12.574Z","dependency_job_id":"7b1363e3-50e6-4572-a631-a0533f8f2867","html_url":"https://github.com/fasttime/Polytype","commit_stats":{"total_commits":313,"total_committers":2,"mean_commits":156.5,"dds":0.4408945686900958,"last_synced_commit":"21a7b61b0409c69e8c0a1967027709aea6ae9843"},"previous_names":["fasttime/proxymi"],"tags_count":49,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fasttime%2FPolytype","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fasttime%2FPolytype/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fasttime%2FPolytype/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fasttime%2FPolytype/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fasttime","download_url":"https://codeload.github.com/fasttime/Polytype/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247312077,"owners_count":20918344,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["class","classes","es2020","inheritance","multiple-inheritance"],"created_at":"2024-11-11T08:17:37.584Z","updated_at":"2025-04-05T09:06:47.255Z","avatar_url":"https://github.com/fasttime.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Polytype · [![npm version][npm badge]][npm url]\n\n**Dynamic multiple inheritance for JavaScript and TypeScript. Without mixins.**\n\n**Polytype** is a library that adds support for dynamic\n[multiple inheritance](https://en.wikipedia.org/wiki/Multiple_inheritance) to JavaScript and\nTypeScript with a simple syntax.\n“Dynamic” means that changes to base classes at runtime are reflected immediately in all derived\nclasses just as programmers would expect when working with single prototype inheritance.\n\nPolytype runs in [**Node.js**](https://nodejs.org/), [**Deno**](https://deno.land/) and in **current\nversions of all major browsers**.\n\n## Contents\n\n- [Contents](#contents)\n- [Features](#features)\n- [Setup Instructions](#setup-instructions)\n  * [In Node.js](#in-nodejs)\n  * [In Deno](#in-deno)\n  * [In the browser](#in-the-browser)\n- [Usage](#usage)\n  * [Inheriting from multiple base classes](#inheriting-from-multiple-base-classes)\n  * [Using methods and properties from multiple base classes](#using-methods-and-properties-from-multiple-base-classes)\n  * [Static methods and properties](#static-methods-and-properties)\n  * [Invoking multiple base constructors](#invoking-multiple-base-constructors)\n  * [`instanceof`](#instanceof)\n  * [`in`](#in)\n  * [`isPrototypeOf`](#isprototypeof)\n  * [Finding the base classes](#finding-the-base-classes)\n  * [Dispatching invocations to multiple base classes](#dispatching-invocations-to-multiple-base-classes)\n  * [Dynamic base class changes](#dynamic-base-class-changes)\n- [TypeScript support](#typescript-support)\n- [Caveats](#caveats)\n  * [`this` in base constructors](#this-in-base-constructors)\n  * [Base classes with private instance members](#base-classes-with-private-instance-members)\n  * [`for...in` iterations](#forin-iterations)\n  * [Member resolution order](#member-resolution-order)\n  * [Ambiguous protected instance members](#ambiguous-protected-instance-members)\n- [Compatibility](#compatibility)\n\n## Features\n\n* Python style multiple inheritance\n* Works in Node.js, Deno and in all new browsers\n* Full TypeScript support\n* Zero dependencies\n* Access to all inherited base class features\n  * constructors\n  * methods, getters and setters, class fields\n  * value properties on base classes and base instance prototypes\n* `in`, `instanceof` and `isPrototypeOf` integration\n\n## Setup Instructions\n\nPolytytpe is available in two flavors: a module build (comprising CommonJS and ECMAScript modules)\nwith exported definitions and a script build where all definitions are accessible through global\nobjects.\nApart from this, both builds provide the same features and are available in the standard package.\n\n### In Node.js\n\nIf you are using Node.js, you can install Polytype with [npm](https://www.npmjs.org).\n\n```console\nnpm install polytype\n```\n\nThen you can import it in your code like any module.\n\n```js\nconst { classes } = require(\"polytype\"); // CommonJS syntax\n```\nor\n```js\nimport { classes } from \"polytype\"; // ECMAScript module syntax\n```\n\nAlternatively, you can import the script build at the start of your application and access Polytype\ndefinitions through global objects.\n\n```js\nrequire(\"polytype/global\"); // CommonJS syntax\n```\nor\n```js\nimport \"polytype/global\"; // ECMAScript module syntax\n```\n\n### In Deno\n\nYou can import the module or script build of Polytype from a CDN of your choice, e.g.\n```js\nimport { classes } from \"https://esm.sh/polytype\"; // Module build\n```\nor\n```js\nimport \"https://esm.sh/polytype/global\"; // Script build\n```\n\n### In the browser\n\nIn an HTML‐based application, the script build of Polytype can be simply embedded.\nJust download\n[polytype.min.js](https://cdn.jsdelivr.net/npm/polytype@0.17.0/lib/polytype.min.js) and include\nit in your HTML file.\n\n```html\n\u003cscript src=\"polytype.min.js\"\u003e\u003c/script\u003e\n```\n\nAlternatively, you can hotlink the script from the latest release package using a CDN of your\nchoice.\n\n```html\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/polytype@0.17.0/lib/polytype.min.js\"\u003e\u003c/script\u003e\n```\n\nIf your browser application already uses ECMAScript modules, you can also import the module build\n(“.mjs”) in contexts where Polytype specific definitions like `classes` are required.\nThis has the advantage to avoid possible naming conflicts on global objects.\n\n```js\nimport { classes } from \"https://cdn.jsdelivr.net/npm/polytype@0.17.0/lib/polytype.min.mjs\";\n```\n\n## Usage\n\n### Inheriting from multiple base classes\n\nFor example, declare a derived class `ColoredCircle` that inherits from both base classes `Circle`\nand `ColoredObject`.\n\n```js\nclass Circle\n{\n    constructor(centerX, centerY, radius = 1)\n    {\n        this.moveTo(centerX, centerY);\n        this.radius = radius;\n    }\n    get diameter() { return this.radius * 2; }\n    set diameter(diameter) { this.radius = diameter / 2; }\n    moveTo(centerX, centerY)\n    {\n        this.centerX = centerX;\n        this.centerY = centerY;\n    }\n    reset()\n    {\n        this.moveTo(0, 0);\n        this.radius = 1;\n    }\n    toString()\n    {\n        return `circle with center (${this.centerX}, ${this.centerY}) and radius ${this.radius}`;\n    }\n}\n\nclass ColoredObject\n{\n    constructor(color) { this.color = color; }\n    static areSameColor(obj1, obj2) { return obj1.color === obj2.color; }\n    paint() { console.log(`painting in ${this.color}`); }\n    reset() { this.color = \"white\"; }\n    toString() { return `${this.color} object`; }\n}\n\nclass ColoredCircle\nextends classes(Circle, ColoredObject) // Base classes as comma‐separated params\n{\n    // Add methods here.\n}\n```\n\n### Using methods and properties from multiple base classes\n\n```js\nconst c = new ColoredCircle();\n\nc.moveTo(42, 31);\nc.radius = 2;\nc.color = \"red\";\nconsole.log(c.centerX, c.centerY);  // 42, 31\nconsole.log(c.diameter);            // 4\nc.paint();                          // \"painting in red\"\n```\n\nAs usual, the keyword `super` invokes a base class method or property accessor when used inside a\nderived class.\n\n```js\nclass ColoredCircle\nextends classes(Circle, ColoredObject)\n{\n    paint()\n    {\n        super.paint(); // Using method paint from some base class\n    }\n}\n```\n\nIf different base classes include a member with the same name, the syntax\n```js\nsuper.class(DirectBaseClass).member\n```\ncan be used to make the member access unambiguous.\n\n```js\nclass ColoredCircle\nextends classes(Circle, ColoredObject)\n{\n    toString()\n    {\n        // Using method toString from base class Circle\n        const circleString = super.class(Circle).toString();\n        return `${circleString} in ${this.color}`;\n    }\n}\n```\n\nMore generally, `super.class(DirectBaseClass)[propertyKey]` can be used to reference a (possibly\ninherited) property of a particular direct base class in the body of a derived class.\n\n**Note:**\nIn TypeScript, the syntax described here cannot be used to access protected instance members, so it\nis currently not possible to disambiguate between protected instance members having the same name,\nthe same index or the same symbol in different base classes.\n\n### Static methods and properties\n\nStatic methods and property accessors are inherited, too.\n\n```js\nColoredCircle.areSameColor(c1, c2)\n```\nsame as\n```js\nColoredObject.areSameColor(c1, c2)\n```\n\n### Invoking multiple base constructors\n\nIn the constructor of a derived class, use arrays to group together parameters to be passed to the\nconstructors of each direct base class.\n\n```js\nclass ColoredCircle\nextends classes(Circle, ColoredObject)\n{\n    constructor(centerX, centerY, radius, color)\n    {\n        super\n        (\n            [centerX, centerY, radius], // Circle constructor params\n            [color]                     // ColoredObject constructor params\n        );\n    }\n}\n```\n\nIf you prefer to keep parameter lists associated to their base classes explicitly without relying on\norder, there is an alternative syntax.\n\n```js\nclass GreenCircle\nextends classes(Circle, ColoredObject)\n{\n    constructor(centerX, centerY, radius)\n    {\n        super\n        (\n            { super: ColoredObject, arguments: [\"green\"] },\n            { super: Circle, arguments: [centerX, centerY, radius] }\n        );\n    }\n}\n```\n\nThere is no need to specify an array of parameters for each direct base constructor.\nIf the parameter arrays are omitted, the base constructors will still be invoked without parameters.\n\n```js\nclass WhiteUnitCircle\nextends classes(Circle, ColoredObject)\n{\n    constructor()\n    {\n        super(); // Base constructors invoked without parameters\n        this.centerX    = 0;\n        this.centerY    = 0;\n        // The radius has been already set to 1 by the Circle constructor.\n        this.color      = \"white\";\n    }\n}\n```\n\n### `instanceof`\n\nThe `instanceof` operator works just as it should.\n\n```js\nconst c = new ColoredCircle();\n\nconsole.log(c instanceof Circle);           // true\nconsole.log(c instanceof ColoredObject);    // true\nconsole.log(c instanceof ColoredCircle);    // true\nconsole.log(c instanceof Object);           // true\nconsole.log(c instanceof Array);            // false\n```\n\nIn pure JavaScript, the expression\n```js\nB.prototype instanceof A\n```\ndetermines if `A` is a base class of class `B`.\n\nPolytype takes care that this test still works well with multiple inheritance.\n\n```js\nconsole.log(ColoredCircle.prototype instanceof Circle);         // true\nconsole.log(ColoredCircle.prototype instanceof ColoredObject);  // true\nconsole.log(ColoredCircle.prototype instanceof ColoredCircle);  // false\nconsole.log(ColoredCircle.prototype instanceof Object);         // true\nconsole.log(Circle.prototype instanceof ColoredObject);         // false\n```\n\n### `in`\n\nThe `in` operator determines whether a property is in an object or in its prototype chain.\nIn the case of multiple inheritance, the prototype “chain” looks more like a directed graph, yet the\nfunction of the `in` operator is the same.\n\n```js\nconst c = new ColoredCircle();\n\nconsole.log(\"moveTo\" in c); // true\nconsole.log(\"paint\" in c);  // true\n```\n\n```js\nconsole.log(\"areSameColor\" in ColoredCircle);   // true\nconsole.log(\"areSameColor\" in Circle);          // false\nconsole.log(\"areSameColor\" in ColoredObject);   // true\n```\n\n### `isPrototypeOf`\n\n`isPrototypeOf` works fine, too.\n\n```js\nconst c = new ColoredCircle();\n\nconsole.log(Circle.prototype.isPrototypeOf(c));         // true\nconsole.log(ColoredObject.prototype.isPrototypeOf(c));  // true\nconsole.log(ColoredCircle.prototype.isPrototypeOf(c));  // true\nconsole.log(Object.prototype.isPrototypeOf(c));         // true\nconsole.log(Array.prototype.isPrototypeOf(c));          // false\n```\n\n```js\nconsole.log(Circle.isPrototypeOf(ColoredCircle));               // true\nconsole.log(ColoredObject.isPrototypeOf(ColoredCircle));        // true\nconsole.log(ColoredCircle.isPrototypeOf(ColoredCircle));        // false\nconsole.log(Object.isPrototypeOf(ColoredCircle));               // false\nconsole.log(Function.prototype.isPrototypeOf(ColoredCircle));   // true\n```\n\n### Finding the base classes\n\nIn single inheritance JavaScript, the direct base class of a derived class is obtained with\n`Object.getPrototypeOf`.\n\n```js\nconst DirectBaseClass = Object.getPrototypeOf(DerivedClass);\n```\n\nIf a class has no explicit `extends` clause, `Object.getPrototypeOf` returns `Function.prototype`,\nthe ancestor of all classes.\n\nOf course this method cannot work with multiple inheritance, since there is no way to return\nmultiple classes without packing them in some kind of structure.\nFor this and other use cases, Polytype exports the function `getPrototypeListOf`, which can be used\nto get an array of direct base classes given a derived class.\n\n```js\nconst { getPrototypeListOf } = require(\"polytype\"); // Or some other kind of import.\n\nfunction getBaseNames(derivedClass)\n{\n    return getPrototypeListOf(derivedClass).map(({ name }) =\u003e name);\n}\n\nconsole.log(getBaseNames(ColoredCircle));   // [\"Circle\", \"ColoredObject\"]\nconsole.log(getBaseNames(Int8Array));       // [\"TypedArray\"]\nconsole.log(getBaseNames(Circle));          // [\"\"] i.e. [Function.prototype.name]\n```\n\nWhen the the script build of Polytype is used, no functions will be exported.\nInstead, `getPrototypeListOf` will be defined globally as `Object.getPrototypeListOf`.\n\n### Dispatching invocations to multiple base classes\n\nSometimes it is useful to have a method or setter invocation dispatched to all direct base classes\nrather than just to one of them.\nCommon examples are event handlers and Angular lifecycle hooks implemented in multiple base classes.\n\nPolytype has no dedicated syntax for this use case: simply override the method or setter in the\nderived class and invoke the base implementations from there.\n\n```js\nclass ColoredCircle\nextends classes(Circle, ColoredObject)\n{\n    reset()\n    {\n        super.class(Circle).reset();\n        super.class(ColoredObject).reset();\n    }\n}\n```\n\nThis can also be done with an iteration instead of referencing the base classes one by one.\n\n```js\nclass ColoredCircle\nextends classes(Circle, ColoredObject)\n{\n    reset()\n    {\n        for (const baseClass of getPrototypeListOf(ColoredCircle))\n            baseClass.reset();\n    }\n}\n```\n\n### Dynamic base class changes\n\nIf a property in a base class is added, removed or modified at runtime, the changes are immediately\nreflected in all derived classes.\n\n```js\nconst c = new ColoredCircle();\n\nCircle.prototype.sayHello = () =\u003e console.log(\"Hello!\");\nc.sayHello(); // \"Hello!\"\n```\n\n## TypeScript support\n\nPolytype has built‐in TypeScript support: you can take advantage of type checking while working with\nmultiple inheritance without installing any additional packages.\nIf you are using an IDE that supports TypeScript code completion like Visual Studio Code, you will\nget multiple inheritance sensitive suggestions as you type.\nA TypeScript version of the `ColoredCircle` sample code above can be found in\n[ColoredCircle.ts](https://github.com/fasttime/Polytype/blob/0.17.0/example/ColoredCircle.ts)\nin the example folder.\n\n## Caveats\n\nNeither JavaScript nor TypeScript offer native support for multiple inheritance of any kind.\nPolytype strives to make up for this deficiency, but some important limitations remain.\n\n### `this` in base constructors\n\nIn single inheritance, the value of `this` inside a constructor and in the constructors of all\nancestor classes is the same object that the `new` operator returns.\nNot so in Polytype multiple inheritance, where the value of `this` inside base constructors is a\nspecial object called a _substitute_.\nSubstitutes are necessary to make base constructors run independently from each other, each one with\nits own fresh instance.\nOnly after all base constructors of a derived class have run, the properties of the substitues are\nmerged into one object.\n\n```js\nlet aThis, bThis, cThis;\n\nclass A\n{\n    constructor()\n    {\n        aThis = this;\n    }\n}\n\nclass B\n{\n    constructor()\n    {\n        bThis = this;\n    }\n}\n\nclass C extends classes(A, B)\n{\n    constructor()\n    {\n        super();\n        cThis = this;\n    }\n}\n\nconst obj = new C();\nconsole.log(aThis === obj);     // Prints false.\nconsole.log(bThis === obj);     // Prints false.\nconsole.log(aThis === bThis);   // Prints false.\nconsole.log(cThis === obj);     // Prints true.\n```\n\nAfter the base constructors have run, the substitutes become detached, meaning that they no longer\nreflect changes to the real instance and vice versa.\nThis may cause problems with classes that store or bind the value of `this` in the constructor to\nuse it later.\n\nFor example, the following code that attaches a click handler to an HTML button will not work as one\nmight expect, because `this` in the event handler refers to a substitute that is unaware of the\n`name` property later assigned to the instance of the derived class.\n\n```js\nclass A\n{\n  constructor()\n  {\n    button.onclick = () =\u003e alert(this.name);\n  }\n}\n\nclass B\n{ }\n\nclass C extends classes(A, B)\n{ }\n\nconst c = new C();\nc.name = 'Test';\nbutton.click(); // Alerts \"undefined\" rather than \"Test\".\n```\n\nWhile Polytype takes some actions to mitigate the effect of detached substitutes, like retargeting\nbound methods if necessary, classes that access the value of `this` in the constructor in order to\nuse it later are generally not safe to subclass.\n\n### Base classes with private instance members\n\nPolytype classes do not inherit private members declared in their base classes.\nFor this reason, extending base classes with private instance members will not work well and likely\nresult in `TypeError`s at runtime.\n\n### `for...in` iterations\n\nWhen only single inheritance is used, a `for...in` iteration over a class constructor enumerates not\nonly names of [enumerable properties][Enumerability and ownership of properties] defined on the\nconstructor object itself, but also names of enumerable properties defined on all base constructors\nin its prototype chain.\nEnumerable properties on class constructors can be defined with a static field, or assigned\ndynamically.\n\n```js\nclass FooBarClass\n{\n    static foo = \"foo\";\n}\n\nFooBarClass.bar = \"bar\";\n\nclass BazClass extends FooBarClass\n{\n    static baz = \"baz\";\n}\n\nfor (const name in BazClass)\n    console.log(name); // Prints \"baz\", \"foo\" and \"bar\".\n```\n\nAs it happens, this behavior no longer holds with Polytype multiple inheritance.\nThe effect is that names of static fields and other enumerable properties defined on a base\nconstructor are not enumerated by `for...in` statements when the inheritance line crosses a class\nlisted in some `extends classes(...)` clause.\n\n```js\nclass BazClass extends classes(FooBarClass)\n{\n    static baz = \"baz\";\n}\n\nfor (const name in BazClass)\n    console.log(name); // Prints just \"baz\".\n```\n\nFor this reason, and because generally [better alternatives exist][Why Use for...in?], iterating\nover Polytype classes and their derived classes with `for...in` is not recommended.\n\n### Member resolution order\n\nMultiple base classes may expose members with the same name, the same index or the same symbol.\nWhen this happens, any unqualified access to one of those members will have to determine the\nimplementation to be used.\nThe approach taken by Polytype is to pick the implementation found in the first direct base class\nthat contains the (possibly inherited) member.\n\n```js\nclass A\n{ }\n\nclass B\n{\n    whoAmI() { console.log(\"B\"); }\n}\n\nclass C\n{\n    whoAmI() { console.log(\"C\"); }\n}\n\nclass ABC extends classes(A, B, C)\n{ }\n\nconst abc = new ABC();\nabc.whoAmI(); // Prints \"B\".\n```\n\nThis is similar to the depth‐first search algorithm of old‐style classes in Python 2, but it is\ndifferent from the behavior of several other programming languages that support multiple\ninheritance, and it may not match your expectations if you come from a C++ background.\n\n### Ambiguous protected instance members\n\nWhen a derived class inherits from multiple base classes, it is possible for inherited members in\ndifferent base classes to share the same property key, i.e. the same name, the same index or the\nsame symbol.\nFor these cases, Polytype provides the syntax `super.class(DirectBaseClass)[propertyKey]` to specify\nthe direct base class containing the member to be accessed.\nThis works all the time in JavaScript and works in TypeScript for any public or static member, but\nresults in a compiler error when applied to a\n[protected](https://www.typescriptlang.org/docs/handbook/2/classes.html#protected) instance member.\n\n```ts\nclass RecordLeft\n{\n    protected id: number;\n}\n\nclass RecordRight\n{\n    protected id: string;\n}\n\nclass Record extends classes(RecordLeft, RecordRight)\n{\n    public printRightId(): void\n    {\n        // error TS2446: Property 'id' is protected…\n        console.log(super.class(RecordRight).id.padStart(10, ' '));\n    }\n}\n```\n\nAs a type‐safe workaround, use an intermediate class to expose the inherited member using a\ndifferent name without making it public.\n\n```ts\nclass RecordRightProxy extends RecordRight\n{\n    protected get rightId(): string\n    {\n        return super.id;\n    }\n}\n\nclass Record extends classes(RecordLeft, RecordRightProxy)\n{\n    public printRightId(): void\n    {\n        console.log(super.rightId.padStart(10, ' ')); // OK\n    }\n}\n```\n\n## Compatibility\n\nPolytype was successfully tested in the following browsers/JavaScript engines.\n\n ![Chrome](https://api.iconify.design/mdi:google-chrome.svg) Chrome 80+\n\u003cbr\u003e\n ![Safari](https://api.iconify.design/mdi:apple-safari.svg) Safari 14+\n\u003cbr\u003e\n ![Edge](https://api.iconify.design/mdi:microsoft-edge.svg) Edge 80+\n\u003cbr\u003e\n ![Firefox](https://api.iconify.design/mdi:firefox.svg) Firefox 74+\n\u003cbr\u003e\n ![Opera](https://api.iconify.design/mdi:opera.svg) Opera 67+\n\u003cbr\u003e\n ![Node.js](https://api.iconify.design/mdi:nodejs.svg) Node.js 16+\n\u003cbr\u003e\n ![Deno](https://api.iconify.design/file-icons:deno.svg) Deno 1.24+\n\nThe minimum supported TypeScript version is 4.7.\n\nBundlers and other tools that process uncompressed Polytype source files are required to parse\nECMAScript 2020 or higher syntax.\n\n[npm badge]: https://badge.fury.io/js/polytype.svg\n[npm url]: https://www.npmjs.com/package/polytype\n[Why Use for...in?]:\nhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in#why_use_for...in\n[Enumerability and ownership of properties]:\nhttps://developer.mozilla.org/en-US/docs/Web/JavaScript/Enumerability_and_ownership_of_properties\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffasttime%2Fpolytype","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffasttime%2Fpolytype","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffasttime%2Fpolytype/lists"}