Hacktoberfest 2026: los issues que los mantenedores marcaron para octubre, abiertos y aptos para principiantes. Explorar issues de Hacktoberfest

A better way to use mixins ?

Abierto
#3,338 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
4/5
Tiempo estimado
3-5 días
Aptitud para principiantes
38/100
Tipo de issue
Documentación
Claridad
Bastante claro
Estado de actividad
Estancado
Stack tecnológico
typescript

Línea de trabajo

Comienza con la página de mixins de TypeScript Handbook enlazada en el issue y revisa el ejemplo proporcionado de Playground. Evalúa cómo encajan el patrón propuesto y sus limitaciones indicadas en la documentación existente y, después, actualiza la guía de mixins con una alternativa precisa y advertencias claras.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

The document gives some examples on how to use mixin here: https://www.typescriptlang.org/docs/handbook/mixins.html

However the 2 proposed solutions has issues:

  • the first one prevent us from having private/protected members, and may generate quite a lot of type deduction error in the function.
  • the second is not that great regarding to type safety.

I think we have a better solution to use mixin, that could be added to the documentation:

class Base {}

// declare the added properties outside of the mixin function
abstract class Mixin {}

class K extends mix(Base, Mixin) { }

Such generic function could be implemented like this:

const MixSrc = Symbol();

type Mix<
            Base  extends          new(...args:any[])=>any,
            Mixin extends abstract new(...args:any[])=>any,
        > = Omit<Base & Mixin, "new"> & (new(...args:ConstructorParameters<Base>) => (InstanceType<Base> & InstanceType<Mixin>))

function mix<
                Base  extends          new(...args:any[]) => any,
                Mixin extends abstract new(...args:any[]) => any
            >(base: Base, mixin: Mixin): Mix<Base, Mixin> {

    class _ extends base {}

    const static_props = Object.getOwnPropertyDescriptors(mixin);
    delete static_props.prototype;
    delete static_props.name;
    Object.defineProperties( _, static_props );

    ((_ as any)[MixSrc] ??= []).push(mixin);

    const hasInstance = mixin[Symbol.hasInstance];
    Object.defineProperty(mixin, Symbol.hasInstance, {
        value: function (instance: any) {
            if( instance.constructor[MixSrc].includes(this) )
                return true;
            return hasInstance.call(this, instance);
        },
        writable: false,
    });

    const instance_props = Object.getOwnPropertyDescriptors(mixin.prototype);
    // @ts-ignore
    delete instance_props.constructor;
    Object.defineProperties( _.prototype, instance_props );

    return _ as any; // well...
}

Playground Link

There are 2 limitations of this method:

  • This may not work if Mixin inherit from another class ( though you could just call mix for each of the Mixin bases ).
  • This will not work if Mixin has private # properties.

If we have private properties, we can do something like:

abstract class Mixin {
     // declare the public/protected interface here
}

type ExcludeProtected<T> = {[K in keyof T]: T[K]}
function addMixin<...>(base): Mix<Base, Mixin> {
      return class _ extends base implements ExcludeProtected<Mixin> {
             // implements Mixin methods here...
             // can't guarantee the protected interface (due to TS limitations).
      } as any;
}

But then Mixin must not inherit from another class.

Lenguaje dominante
TypeScript
Estrellas
2.6k
Forks
1.5k
Merge medio
2 d 21 h
PR fusionados (30 d)
7

Preparar el entorno

Aún no hemos revisado los archivos de configuración de este proyecto. Empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de microsoft/TypeScript-Website

Todos los issues de microsoft/TypeScript-Website

Issues similares

Más issues de TypeScript

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.