{"_id":"@alizurchik/ts-mixin","_rev":"6-34b61e78d4aa8884de054edd744ae110","name":"@alizurchik/ts-mixin","description":"Mixin function that brings power of mixin to TypeScript without headache","dist-tags":{"latest":"1.0.2"},"versions":{"1.0.0":{"name":"@alizurchik/ts-mixin","version":"1.0.0","description":"Mixin function that brings power of mixin to TypeScript without headache","main":"index.js","scripts":{"test":"npm run build && ava","build":"tsc","preversion":"npm test","postversion":"git push && git push --tags"},"keywords":["mixin","typescript","javascript"],"author":{"name":"Alexey Lizurchik","email":"al.lizurchik@gmail.com","url":"http://likerrr.ru"},"license":"MIT","dependencies":{},"devDependencies":{"ava":"^0.16.0","typescript":"^2.0.2"},"files":["index.js","index.d.ts"],"ava":{"verbose":true,"require":["babel-register"],"babel":{"presets":["es2015"]}},"gitHead":"2be50bb9f7b1ce3c2ca660cc7afd00804048d5e5","_id":"@alizurchik/ts-mixin@1.0.0","_shasum":"fc45becb3719affe3e6c882982e30c98aa8e108e","_from":".","_npmVersion":"3.8.6","_nodeVersion":"5.11.0","_npmUser":{"name":"alizurchik","email":"al.lizurchik@gmail.com"},"dist":{"shasum":"fc45becb3719affe3e6c882982e30c98aa8e108e","tarball":"https://registry.npmjs.org/@alizurchik/ts-mixin/-/ts-mixin-1.0.0.tgz","integrity":"sha512-kbAslQ+VSyQwWl4w5wZK06R8VjGKJ802mofQfDalrIUsNoK6ASDjx/JrU3eQaiopit6TI4zSJ9Csil39321J4g==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIApG5Ph6Iwtn/rPYLmoYEcBUmwnOAz3L5eyM55hkm1rUAiBx37ouDTKqwsDLJojreHw2O5tEoywQpIDuXCAYe2eXeQ=="}]},"maintainers":[{"name":"alizurchik","email":"al.lizurchik@gmail.com"}],"_npmOperationalInternal":{"host":"packages-16-east.internal.npmjs.com","tmp":"tmp/ts-mixin-1.0.0.tgz_1473430876354_0.41786161297932267"},"directories":{}},"1.0.1":{"name":"@alizurchik/ts-mixin","version":"1.0.1","description":"Mixin function that brings power of mixin to TypeScript without headache","main":"index.js","scripts":{"test":"npm run build && ava","build":"tsc","preversion":"npm test","postversion":"git push && git push --tags"},"keywords":["mixin","typescript","javascript"],"author":{"name":"Alexey Lizurchik","email":"al.lizurchik@gmail.com","url":"http://likerrr.ru"},"license":"MIT","dependencies":{},"devDependencies":{"ava":"^0.16.0","typescript":"^2.0.2"},"files":["index.js","index.d.ts"],"ava":{"verbose":true,"require":["babel-register"],"babel":{"presets":["es2015"]}},"gitHead":"816743399880d5b720f80d24b1a073ff63de37f9","_id":"@alizurchik/ts-mixin@1.0.1","_shasum":"1f08cd65e049f595516dd6b1676fb894ee302f4c","_from":".","_npmVersion":"3.8.6","_nodeVersion":"5.11.0","_npmUser":{"name":"alizurchik","email":"al.lizurchik@gmail.com"},"dist":{"shasum":"1f08cd65e049f595516dd6b1676fb894ee302f4c","tarball":"https://registry.npmjs.org/@alizurchik/ts-mixin/-/ts-mixin-1.0.1.tgz","integrity":"sha512-bpisijPMxNGKpFedqtqqa/t17Dxhrc1uxFWD7ImF+w0ypErh1RIVY1guUNgvVXXv6czQV73sChFwS9JLQokm6Q==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDTKDL8NbIwbyCNk8ZgeyPDre4r8B65rAOzxu3Nhsi3ZQIga5uOy5SlCU2ubbkNR93HFy9/GGTOpEjR9hSBtSiFTp4="}]},"maintainers":[{"name":"alizurchik","email":"al.lizurchik@gmail.com"}],"_npmOperationalInternal":{"host":"packages-16-east.internal.npmjs.com","tmp":"tmp/ts-mixin-1.0.1.tgz_1473746644231_0.7251154389232397"},"directories":{}},"1.0.2":{"name":"@alizurchik/ts-mixin","version":"1.0.2","description":"Mixin function that brings power of mixin to TypeScript without headache","main":"index.js","scripts":{"test":"npm run build && ava","build":"tsc","preversion":"npm test","postversion":"git push && git push --tags"},"repository":{"type":"git","url":"git+https://github.com/likerRr/ts-mixin.git"},"bugs":{"url":"https://github.com/likerRr/ts-mixin/issues"},"keywords":["mixin","typescript","javascript","ts","composition","extend","inheritance"],"author":{"name":"Alexey Lizurchik","email":"al.lizurchik@gmail.com","url":"http://likerrr.ru"},"license":"MIT","dependencies":{},"devDependencies":{"ava":"^0.16.0","typescript":"^2.0.2"},"files":["index.js","index.d.ts"],"ava":{"verbose":true,"require":["babel-register"],"babel":{"presets":["es2015"]}},"gitHead":"d599df25b4e8652bbc19e7a12a9582003c2edbf7","homepage":"https://github.com/likerRr/ts-mixin#readme","_id":"@alizurchik/ts-mixin@1.0.2","_shasum":"93bacb368246fdd5af59d0d1ab1d4b1da7664889","_from":".","_npmVersion":"3.8.6","_nodeVersion":"5.11.0","_npmUser":{"name":"alizurchik","email":"al.lizurchik@gmail.com"},"dist":{"shasum":"93bacb368246fdd5af59d0d1ab1d4b1da7664889","tarball":"https://registry.npmjs.org/@alizurchik/ts-mixin/-/ts-mixin-1.0.2.tgz","integrity":"sha512-Saj9baiw4PsJuW70LXN/GvihhJ6vHfp9Al+M9Dt7CZAOWwgJja5c3kAJYbNvtEezSGerfKPmebAuKtgO4EW2YQ==","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFijz7p0gCo7csbnSEJylJR7ByAIUtgRTsE0dgXBq1ZdAiB7udmmeEWzyXWpJdklwYelee7CInr+5sMl6q9nqm6OYA=="}]},"maintainers":[{"name":"alizurchik","email":"al.lizurchik@gmail.com"}],"_npmOperationalInternal":{"host":"packages-16-east.internal.npmjs.com","tmp":"tmp/ts-mixin-1.0.2.tgz_1473747399382_0.2735855858772993"},"directories":{}}},"readme":"# TypeScript Mixin Pattern Implementation\r\nTS mixin function with autocomplete and without headache.\r\n\r\n### About\r\nAs far as every TS developer knows, TS doesn't provide any built-in ability for mixins usage.\r\nSure, they offer [\"polyfill\"](https://www.typescriptlang.org/docs/handbook/mixins.html), but \r\nunfortunately this example of mixins implementation is very verbose and it requires a lot of boilerplate code to add that should be maintained.\r\nI'm talking about such construction (from official TS example):\r\n\r\n```javascript\r\nclass SmartObject implements Disposable, Activatable {\r\n    // implementation details...\r\n\r\n    // Disposable                   // Since Disposable and Activatable \r\n    isDisposed: boolean = false;    // are interfaces you have to\r\n    dispose: () => void;            // keep this ugly implementations\r\n    // Activatable                  // of all of their methods. It becomes \r\n    isActive: boolean = false;      // an abuse when one of interfaces \r\n    activate: () => void;           // has changed and you should update\r\n    deactivate: () => void;         // implementation in every \"implementers\"\r\n}\r\n\r\n// and of course you should call special function which does \"mixin magic\"\r\napplyMixins(SmartObject, [Disposable, Activatable]);\r\n```\r\n\r\nThanks to [falsandtru](https://github.com/falsandtru) I found [his workaround](https://github.com/Microsoft/TypeScript/issues/2919#issuecomment-225398629)\r\nand wrapped it in package to use it in any of your projects until [TS](https://github.com/Microsoft/TypeScript/issues/2919) (or tc39?) came up with \r\nmore suitable solution.\r\n\r\n### Usage example\r\n\r\nFirst, install the package `npm install @alizurchik/ts-mixin`\r\n\r\nThen, explore the example:\r\n\r\n```javascript\r\nimport {Mixin} from '@alizurchik/ts-mixin';\r\n\r\n// mixins are simple classes\r\nclass A {\r\n  static a = 'A';\r\n  ap = 'a';\r\n\r\n  am() {\r\n    return this.ap;\r\n  }\r\n}\r\n\r\nclass B {\r\n  static b = 'B';\r\n  bp = 'b';\r\n\r\n  bm() {\r\n    return this.bp;\r\n  }\r\n}\r\n\r\ninterface AB extends B, A {} // <= You need this to enable typeguards and autocomplete features\r\nclass X extends Mixin<AB>(B, A) {\r\n  static x = 'X';\r\n  xp = 'x';\r\n\r\n  xm() {\r\n    return this.xp;\r\n  }\r\n}\r\n\r\n/* At this moment class X is mixed with classes A and B\r\n   X\r\n   | - a = 'A'\r\n     - b = 'B'\r\n     - x = 'X'\r\n     - prototype (X)\r\n        | - xm()\r\n            | - __proto__\r\n                 | - am()\r\n                 | - bm()\r\n*/\r\n\r\nconst x = new X();\r\n\r\n/*\r\n   x\r\n   | - ap = 'a'\r\n     - bp = 'b'\r\n     - xp = 'x'\r\n     - __ptoto__ = X\r\n*/\r\n```\r\n\r\nThis way you can simply mix functionality. Few words to add about constructors. Since `Mixin` function uses\r\n`reduce` to walk through it's parameters then classes will be instantiated from the end. Take a look at these \r\nsimple examples:\r\n\r\n```javascript\r\nimport {Mixin} from '@alizurchik/ts-mixin';\r\n\r\n// mixins are simple classes\r\nclass A {\r\n  constructor() {\r\n    console.log('A');\r\n  }\r\n}\r\n\r\nclass B {\r\n  constructor() {\r\n    console.log('B');\r\n  }\r\n}\r\n\r\ninterface AB extends B, A {}\r\nclass XAB extends Mixin<AB>(B, A) {\r\n  constructor() {\r\n    super(); // mandatory! it will trigger each mixed class's constructor\r\n    console.log('X');\r\n  }\r\n}\r\n\r\ninterface AB extends B, A {}\r\n\r\nclass XAB extends Mixin<AB>(B, A) /*reverse order*/ { \r\n  constructor() {\r\n    super(); // mandatory! it will trigger each mixed class's constructor\r\n    console.log('X');\r\n  }\r\n}\r\n\r\nclass XBA extends Mixin<AB>(A, B) /*direct order*/ {\r\n  constructor() {\r\n    super(); // mandatory! it will trigger each mixed class's constructor\r\n    console.log('X');\r\n  }\r\n}\r\n\r\nnew XAB();\r\nconsole.log('---');\r\nnew XBA();\r\n\r\n/* output =>\r\nA\r\nB\r\nX\r\n---\r\nB\r\nA\r\nX\r\n*/\r\n```\r\n\r\n### Known limitation\r\n\r\n#### Access to static properties\r\nTypeScript compiler will complain if you try to access static property via dot. Use square brackets instead:\r\n\r\n```javascript\r\nX.a; // <= Error: TS2339\r\nX['a']; // Ok\r\n```\r\n\r\nBut autocomplete feature still works:\r\n\r\n![](docs/autocomplete_static_prop.gif)\r\n\r\nIf someone knows a workaround for this issue PR is highly welcome :exclamation:\r\n\r\n#### Mixins + Extending\r\nYou can't extend and use mixins at the same time. It means your class could either extend one class\r\nor be mixed with other class(es). Again, if someone knows a workaround, PRs are accepted. \r\n\r\nIf you really need it you should use [TS's solution](https://www.typescriptlang.org/docs/handbook/mixins.html).\r\n","maintainers":[{"name":"alizurchik","email":"al.lizurchik@gmail.com"}],"time":{"modified":"2022-06-12T14:31:36.930Z","created":"2016-09-09T14:21:17.851Z","1.0.0":"2016-09-09T14:21:17.851Z","1.0.1":"2016-09-13T06:04:06.165Z","1.0.2":"2016-09-13T06:16:41.334Z"},"keywords":["mixin","typescript","javascript","ts","composition","extend","inheritance"],"author":{"name":"Alexey Lizurchik","email":"al.lizurchik@gmail.com","url":"http://likerrr.ru"},"license":"MIT","readmeFilename":"README.md","homepage":"https://github.com/likerRr/ts-mixin#readme","repository":{"type":"git","url":"git+https://github.com/likerRr/ts-mixin.git"},"bugs":{"url":"https://github.com/likerRr/ts-mixin/issues"},"users":{}}