Skip to content

Commit b191267

Browse files
johnjenkinsJohn Jenkins
andauthored
fix(types): new MixedInCtor type to make Mixin components type-safe (#6422)
* fix(types): new `MixedInCtor` type to make `Mixin` components type-safe * chore: jsdoc * chore: prettier * chore: added todo --------- Co-authored-by: John Jenkins <john.jenkins@nanoporetech.com>
1 parent 5341bf4 commit b191267

File tree

2 files changed

+25
-12
lines changed

2 files changed

+25
-12
lines changed

src/declarations/stencil-public-runtime.ts

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ type CustomMethodDecorator<T> = (
44
descriptor: TypedPropertyDescriptor<T>,
55
) => TypedPropertyDescriptor<T> | void;
66

7-
type UnionToIntersection<U> = (U extends any ? (x: U) => void : never) extends (x: infer I) => void ? I : never;
7+
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
8+
9+
type MixinInstance<F> = F extends (base: MixedInCtor) => MixedInCtor<infer I> ? I : never;
810

911
export interface ComponentDecorator {
1012
(opts?: ComponentOptions): ClassDecorator;
@@ -425,33 +427,43 @@ export declare function readTask(task: RafCallback): void;
425427
*/
426428
export declare const setErrorHandler: (handler: ErrorHandler) => void;
427429

428-
export type MixinFactory = <TBase extends new (...args: any[]) => any>(
429-
base: TBase,
430-
) => abstract new (...args: ConstructorParameters<TBase>) => any;
430+
/**
431+
* @deprecated - Use `MixedInCtor` instead:
432+
* ```ts
433+
* import { MixedInCtor } from '@stencil/core';
434+
*
435+
* const AFactoryFn = <B extends MixedInCtor>(Base: B) => {class A extends Base { propA = A }; return A;}
436+
* ```
437+
*/
438+
export type MixinFactory = (base: MixedInCtor) => MixedInCtor;
439+
440+
// TODO ^ do not remove. Just do not export when deprecated.
441+
442+
export type MixedInCtor<T = {}> = new (...args: any[]) => T;
431443

432444
/**
433445
* Compose multiple mixin classes into a single constructor.
434446
* The resulting class has the combined instance types of all mixed-in classes.
435447
*
436448
* Example:
437-
* ```
438-
* import { Mixin, MixinFactory } from '@stencil/core';
449+
* ```ts
450+
* import { Mixin, MixedInCtor } from '@stencil/core';
439451
*
440-
* const AWrap: MixinFactory = (Base) => {class A extends Base { propA = A }; return A;}
441-
* const BWrap: MixinFactory = (Base) => {class B extends Base { propB = B }; return B;}
442-
* const CWrap: MixinFactory = (Base) => {class C extends Base { propC = C }; return C;}
452+
* const AWrap = <B extends MixedInCtor>(Base: B) => {class A extends Base { propA = A }; return A;}
453+
* const BWrap = <B extends MixedInCtor>(Base: B) => {class B extends Base { propB = B }; return B;}
454+
* const CWrap = <B extends MixedInCtor>(Base: B) => {class C extends Base { propC = C }; return C;}
443455
*
444456
* class X extends Mixin(AWrap, BWrap, CWrap) {
445457
* render() { return <div>{this.propA} {this.propB} {this.propC}</div>; }
446458
* }
447459
* ```
448460
*
449461
* @param mixinFactories mixin factory functions that return a class which extends from the provided class.
450-
* @returns a class that that is composed from extending each of the provided classes in the order they were provided.
462+
* @returns a class that is composed from extending each of the provided classes in the order they were provided.
451463
*/
452-
export declare function Mixin<TMixins extends readonly MixinFactory[]>(
464+
export declare function Mixin<const TMixins extends readonly MixinFactory[]>(
453465
...mixinFactories: TMixins
454-
): abstract new (...args: any[]) => UnionToIntersection<InstanceType<ReturnType<TMixins[number]>>>;
466+
): abstract new (...args: any[]) => UnionToIntersection<MixinInstance<TMixins[number]>>;
455467

456468
/**
457469
* This file gets copied to all distributions of stencil component collections.

src/internal/stencil-core/index.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export {
4141
Host,
4242
Listen,
4343
Method,
44+
MixedInCtor,
4445
Mixin,
4546
MixinFactory,
4647
Prop,

0 commit comments

Comments
 (0)